diff --git a/src/tools/msvc.jam b/src/tools/msvc.jam index 447187249a..85cb8e1539 100644 --- a/src/tools/msvc.jam +++ b/src/tools/msvc.jam @@ -689,7 +689,7 @@ 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++ $(<) : $(>) ; } @@ -697,7 +697,7 @@ 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++ $(<) : $(>) ; } @@ -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) { @@ -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 * ) @@ -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 * ) @@ -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 @@ -770,18 +776,18 @@ 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) } @@ -789,14 +795,14 @@ 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++ $(<) : $(>) ; } @@ -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) { @@ -1005,6 +1013,7 @@ 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 is a dirty trick, needed because @@ -1012,6 +1021,8 @@ class msvc-pch-generator : pch-generator # broken. For more detailed information see: # https://zigzag.cs.msu.su:7813/boost.build/ticket/111 $(pch-source) + $(pch-header) + $(pch-header-root) [ $(property-set).raw ] ] : $(pch-header) ] ; @@ -1025,6 +1036,7 @@ class msvc-pch-generator : pch-generator } return [ $(generated[1]).add-raw $(pch-header) + $(pch-header-root) $(pch-file) ] $(generated[2-]) ; } } diff --git a/test/pch.py b/test/pch.py index bcb9bd57af..dba084ff69 100644 --- a/test/pch.py +++ b/test/pch.py @@ -15,12 +15,15 @@ t.write("jamroot.jam", """ import pch ; project : requirements on ; -cpp-pch pch : a/pch.hpp ; -cpp-pch pch-afx : a/pch.hpp : HELLO ; -cpp-pch pch-msvc-source : a/pch.hpp : msvc:a/pch.cpp ; +cpp-pch pch : pch.hpp ; +cpp-pch pch-afx : pch.hpp : HELLO ; +cpp-pch pch-msvc-source : pch.hpp : msvc:pch.cpp ; exe hello : hello.cpp pch ; exe hello-afx : hello-afx.cpp pch-afx : 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 = """\ @@ -31,13 +34,13 @@ 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 +t.write("pch.cpp", """#include """) -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); } """) @@ -45,6 +48,7 @@ class TestClass 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 @@ -52,10 +56,12 @@ class TestClass # 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") @@ -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 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()