Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msvc: fix -I"" for same directory pch header #231

Merged
merged 1 commit into from
Apr 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions src/tools/msvc.jam
Original file line number Diff line number Diff line change
Expand Up @@ -689,15 +689,15 @@ rule compile.c ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TC CFLAGS ;
compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
compile-c-c++ $(<) : $(>) ;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually not sure why it was done like this, maybe I miss something, like it's need to run header scanning or something else?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe header scanning. But not sure on that. It does seem rather weird.

}


rule compile.c.preprocess ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TC CFLAGS ;
preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
preprocess-c-c++ $(<) : $(>) ;
}


Expand All @@ -706,6 +706,8 @@ rule compile.c.pch ( targets + : sources * : properties * )
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets[1]) : -TC CFLAGS ;
get-rspline $(targets[2]) : -TC CFLAGS ;
local pch-header = [ on $(<) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<) = $(sources:G=) ;
local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
if $(pch-source)
{
Expand Down Expand Up @@ -738,14 +740,14 @@ toolset.flags msvc YLOPTION : "-Yl" ;
# for each source file by rule archive, as in this case compiler must be used
# to create a single PDB for our library.
#
actions compile-c-c++ bind PDB_NAME PCH_HEADER
actions compile-c-c++ bind PDB_NAME PCH_HEADER_AS_SPELLED PCH_FILE
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -c -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -I"$(PCH_HEADER:D)" -FI"$(PCH_HEADER:D=)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE)) $(.CC.FILTER)
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -c -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -FI"$(PCH_HEADER_AS_SPELLED:T)" -Yu"$(PCH_HEADER_AS_SPELLED:T)" -Fp"$(PCH_FILE:W)" $(CC_RSPLINE)) $(.CC.FILTER)
}

actions preprocess-c-c++ bind PDB_NAME PCH_HEADER
actions preprocess-c-c++ bind PDB_NAME PCH_HEADER_AS_SPELLED PCH_FILE
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -P -Fi"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -I"$(PCH_HEADER:D)" -FI"$(PCH_HEADER:D=)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[1]:W)" -P -Fi"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -FI"$(PCH_HEADER_AS_SPELLED:T)" -Yu"$(PCH_HEADER_AS_SPELLED:T)" -Fp"$(PCH_FILE:W)" $(CC_RSPLINE))
}

rule compile-c-c++ ( targets + : sources * )
Expand All @@ -754,6 +756,8 @@ rule compile-c-c++ ( targets + : sources * )
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
PDB_NAME on $(<) = $(<[1]:S=.pdb) ;
LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
local pch-header = [ on $(<[1]) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<[1]) = $(pch-header:G=) ;
}

rule preprocess-c-c++ ( targets + : sources * )
Expand All @@ -762,6 +766,8 @@ rule preprocess-c-c++ ( targets + : sources * )
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
PDB_NAME on $(<) = $(<:S=.pdb) ;
LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ;
local pch-header = [ on $(<[1]) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<[1]) = $(pch-header:G=) ;
}

# Action for running the C/C++ compiler using precompiled headers. In addition
Expand All @@ -770,33 +776,33 @@ rule preprocess-c-c++ ( targets + : sources * )
#
# The global .escaped-double-quote variable is used to avoid messing up Emacs
# syntax highlighting in the messy N-quoted code below.
actions compile-c-c++-pch
actions compile-c-c++-pch bind PCH_HEADER_AS_SPELLED
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -I"$(>[1]:D)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) @($(<[1]:W).cpp:<=":>=":E=$(.hash)include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl)) $(.CC.FILTER)
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -Yc"$(PCH_HEADER_AS_SPELLED:T)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) @($(<[1]:W).cpp:<=":>=":E=$(.hash)include $(.escaped-double-quote)$(PCH_HEADER_AS_SPELLED:T)$(.escaped-double-quote)$(.nl)) $(.CC.FILTER)
}


# Action for running the C/C++ compiler using precompiled headers. An already
# built source file for compiling the precompiled headers is expected to be
# given as one of the source parameters.
actions compile-c-c++-pch-s
actions compile-c-c++-pch-s bind PCH_HEADER_AS_SPELLED
{
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -I"$(>[1]:D)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) $(.CC.FILTER)
$(.SETUP) $(.CC) @($(<[1]:W).rsp:O=FC:<=@":>=":E="$(>[2]:W)" -c -Fo"$(<[2]:W)" -Yc"$(PCH_HEADER_AS_SPELLED:T)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE)) $(.CC.FILTER)
}


rule compile.c++ ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TP C++FLAGS ;
compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
compile-c-c++ $(<) : $(>) ;
}

rule compile.c++.preprocess ( targets + : sources * : properties * )
{
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets) : -TP C++FLAGS ;
preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
preprocess-c-c++ $(<) : $(>) ;
}


Expand All @@ -805,6 +811,8 @@ rule compile.c++.pch ( targets + : sources * : properties * )
set-setup-command $(targets) : $(properties) ;
get-rspline $(targets[1]) : -TP C++FLAGS ;
get-rspline $(targets[2]) : -TP C++FLAGS ;
local pch-header = [ on $(<) return $(PCH_HEADER) ] ;
PCH_HEADER_AS_SPELLED on $(<) = $(sources:G=) ;
local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
if $(pch-source)
{
Expand Down Expand Up @@ -1005,13 +1013,16 @@ class msvc-pch-generator : pch-generator

# If we do not have the PCH source - that is fine. We will just create a
# temporary .cpp file in the action.
local pch-header-root = [ $(pch-header).path ] ;
local generated = [ generator.run $(project) $(name)
: [ property-set.create
# Passing of <pch-source> is a dirty trick, needed because
# non-composing generators with multiple inputs are subtly
# broken. For more detailed information see:
# https://zigzag.cs.msu.su:7813/boost.build/ticket/111
<pch-source>$(pch-source)
<pch-header>$(pch-header)
<include>$(pch-header-root)
[ $(property-set).raw ] ]
: $(pch-header) ] ;

Expand All @@ -1025,6 +1036,7 @@ class msvc-pch-generator : pch-generator
}

return [ $(generated[1]).add-raw <pch-header>$(pch-header)
<include>$(pch-header-root)
<pch-file>$(pch-file) ] $(generated[2-]) ;
}
}
Expand Down
47 changes: 36 additions & 11 deletions test/pch.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
t.write("jamroot.jam", """
import pch ;
project : requirements <warnings-as-errors>on ;
cpp-pch pch : a/pch.hpp ;
cpp-pch pch-afx : a/pch.hpp : <define>HELLO ;
cpp-pch pch-msvc-source : a/pch.hpp : <toolset>msvc:<source>a/pch.cpp ;
cpp-pch pch : pch.hpp ;
cpp-pch pch-afx : pch.hpp : <define>HELLO ;
cpp-pch pch-msvc-source : pch.hpp : <toolset>msvc:<source>pch.cpp ;
exe hello : hello.cpp pch ;
exe hello-afx : hello-afx.cpp pch-afx : <define>HELLO ;
exe hello-msvc-source : hello-msvc-source.cpp pch-msvc-source ;

cpp-pch subdir-pch : a/pch_different.hpp ;
exe hello-subdir : a/hello.cpp subdir-pch ;
""")

pch_content = """\
Expand All @@ -31,31 +34,34 @@ class TestClass
TestClass( int, int ) {}
};
"""
t.write("a/pch.hpp", pch_content)
t.write("pch.hpp", pch_content)
t.copy("pch.hpp", "a/pch_different.hpp")

t.write("a/pch.cpp", """#include <pch.hpp>
t.write("pch.cpp", """#include <pch.hpp>
""")

toolset = BoostBuild.get_toolset()
for name in ("hello.cpp", "hello-afx.cpp", "hello-msvc-source.cpp"):
for name in ("hello.cpp", "hello-afx.cpp", "hello-msvc-source.cpp", "a/hello.cpp", "a/hello-rel.cpp"):
t.write(name, """int main() { TestClass c(1, 2); }
""")

t.run_build_system()
t.expect_addition("bin/$toolset/debug*/hello.exe")
t.expect_addition("bin/$toolset/debug*/hello-afx.exe")
t.expect_addition("bin/$toolset/debug*/hello-msvc-source.exe")
t.expect_addition("bin/$toolset/debug*/hello-subdir.exe")


# Now make the header unusable, replace its content with some garbage, but
# preserve the size and timestamp to fool the compiler. If everything is OK,
# B2 will not recreate PCH, and compiler will happily use pre-compiled
# header, not noticing that the real header is bad.

t.rename("a/pch.hpp", "a/pch.hpp.orig")
s = "THIS WILL NOT COMPILE. "
t.write("a/pch.hpp", s + (len(pch_content) - len(s)) * 'x')
t.copy_timestamp("a/pch.hpp.orig", "a/pch.hpp")
t.rename("pch.hpp", "pch.hpp.orig")
s = """#error PCH REBUILD HAPPEND
THIS WILL NOT COMPILE
"""
t.write("pch.hpp", s + (len(pch_content) - len(s)) * 'x')
t.copy_timestamp("pch.hpp.orig", "pch.hpp")

t.rm("bin/$toolset/debug*/hello.obj")
t.rm("bin/$toolset/debug*/hello-afx.obj")
Expand All @@ -66,4 +72,23 @@ class TestClass
t.expect_addition("bin/$toolset/debug*/hello-afx.obj")
t.expect_addition("bin/$toolset/debug*/hello-msvc-source.obj")

t.rm("bin")
t.copy("a/pch_different.hpp", "pch.hpp")
t.rename("a", "b")
t.write("b/jamfile.jam", """\
import pch ;
project : requirements <warnings-as-errors>on ;
cpp-pch pch : pch_different.hpp ;
exe hello : hello.cpp pch ;
cpp-pch pch-rel : ../pch.hpp ;
exe hello-rel : hello-rel.cpp pch-rel ;
""")
t.run_build_system(["-d+2", "b"])
t.expect_addition("b/bin/$toolset/debug*/hello.exe")
t.expect_addition("b/bin/$toolset/debug*/hello-rel.exe")
t.rm("b/bin")
t.run_build_system(["-d+2"], subdir="b")
t.expect_addition("b/bin/$toolset/debug*/hello.exe")
t.expect_addition("b/bin/$toolset/debug*/hello-rel.exe")

t.cleanup()