2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-15 00:52:16 +00:00

Implement a preprocessed rule for generating preprocessed source files. Refs #5390. This is not yet complete as it is only implemented for gcc and msvc.

[SVN r71094]
This commit is contained in:
Steven Watanabe
2011-04-07 23:41:19 +00:00
parent 9add5f4ab2
commit 27a60c17b6
6 changed files with 184 additions and 0 deletions

View File

@@ -118,6 +118,14 @@ boost-build build-system ;
file must be compiled with special properties.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>preprocessed</literal></term>
<indexterm><primary>preprocessed</primary></indexterm>
<listitem><para>Creates an preprocessed source file. The arguments follow the
<link linkend="bbv2.main-target-rule-syntax">common syntax</link>.</para></listitem>
</varlistentry>
<varlistentry>
<term><literal>glob</literal></term>

53
v2/test/preprocessor.py Executable file
View File

@@ -0,0 +1,53 @@
#!/usr/bin/python
# Copyright 2003 Vladimir Prus
# Copyright 2011 Steven Watanabe
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# Test the C/C++ preprocessor.
import BoostBuild
t = BoostBuild.Tester()
t.write("jamroot.jam", """
project ;
preprocessed hello : hello.cpp ;
preprocessed a : a.c ;
exe hello.exe : hello a : <define>FAIL ;
""")
t.write("hello.cpp", """
#ifndef __cplusplus
#error "This file must be compiled as C++"
#endif
#ifdef FAIL
#error "Not preprocessed?"
#endif
extern "C" int foo();
int main() { return foo(); }
""")
t.write("a.c", """
/* This will not compile unless in C mode. */
#ifdef __cplusplus
#error "This file must be compiled as C"
#endif
#ifdef FAIL
#error "Not preprocessed?"
#endif
int foo()
{
int new = 0;
new = (new+1)*7;
return new;
}
""")
t.run_build_system()
t.expect_addition("bin/$toolset/debug/hello.ii")
t.expect_addition("bin/$toolset/debug/a.i")
t.expect_addition("bin/$toolset/debug/hello.exe")
t.cleanup()

View File

@@ -26,6 +26,7 @@ import stage ;
import symlink ;
import toolset ;
import type ;
import targets ;
import types/register ;
import utility ;
import virtual-target ;
@@ -603,6 +604,48 @@ generators.register
generators.override builtin.prebuilt : builtin.lib-generator ;
class preprocessed-target-class : basic-target
{
import generators ;
rule construct ( name : sources * : property-set )
{
local result = [ generators.construct [ project ]
$(name) : PREPROCESSED_CPP : $(property-set) : $(sources) ] ;
if ! $(result)
{
result = [ generators.construct [ project ]
$(name) : PREPROCESSED_C : $(property-set) : $(sources) ] ;
}
if ! $(result)
{
local s ;
for x in $(sources)
{
s += [ $(x).name ] ;
}
local p = [ project ] ;
errors.user-error
"In project" [ $(p).name ] :
"Could not construct preprocessed file \"$(name)\" from $(s:J=, )." ;
}
return $(result) ;
}
}
rule preprocessed ( name : sources * : requirements * : default-build * :
usage-requirements * )
{
local project = [ project.current ] ;
return [ targets.main-target-alternative
[ new preprocessed-target-class $(name) : $(project)
: [ targets.main-target-sources $(sources) : $(name) ]
: [ targets.main-target-requirements $(r) : $(project) ]
: [ targets.main-target-default-build $(default-build) : $(project) ]
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
] ] ;
}
IMPORT $(__name__) : preprocessed : : preprocessed ;
class compile-action : action
{

View File

@@ -284,6 +284,8 @@ if [ os.name ] = NT
JAMSHELL = % ;
}
generators.register-c-compiler gcc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>gcc ;
generators.register-c-compiler gcc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>gcc ;
generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : <toolset>gcc ;
generators.register-c-compiler gcc.compile.c : C : OBJ : <toolset>gcc ;
generators.register-c-compiler gcc.compile.asm : ASM : OBJ : <toolset>gcc ;
@@ -507,6 +509,37 @@ actions compile.c.pch
"$(CONFIG_COMMAND)" -x c-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
}
rule compile.c++.preprocess ( targets * : sources * : properties * )
{
setup-threading $(targets) : $(sources) : $(properties) ;
setup-fpic $(targets) : $(sources) : $(properties) ;
setup-address-model $(targets) : $(sources) : $(properties) ;
# Some extensions are compiled as C++ by default. For others, we need to
# pass -x c++. We could always pass -x c++ but distcc does not work with it.
if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C
{
LANG on $(<) = "-x c++" ;
}
DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
}
rule compile.c.preprocess ( targets * : sources * : properties * )
{
setup-threading $(targets) : $(sources) : $(properties) ;
setup-fpic $(targets) : $(sources) : $(properties) ;
setup-address-model $(targets) : $(sources) : $(properties) ;
# If we use the name g++ then default file suffix -> language mapping does
# not work. So have to pass -x option. Maybe, we can work around this by
# allowing the user to specify both C and C++ compiler names.
#if $(>:S) != .c
#{
LANG on $(<) = "-x c" ;
#}
DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
}
rule compile.c++ ( targets * : sources * : properties * )
{
setup-threading $(targets) : $(sources) : $(properties) ;
@@ -570,6 +603,16 @@ actions compile.c bind PCH_FILE
"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
}
actions compile.c++.preprocess bind PCH_FILE
{
"$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>:W)" -E >"$(<:W)"
}
actions compile.c.preprocess bind PCH_FILE
{
"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>)" -E >$(<)
}
actions compile.fortran
{
"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)"

View File

@@ -325,6 +325,14 @@ rule compile.c ( targets + : sources * : properties * )
}
rule compile.c.preprocess ( targets + : sources * : properties * )
{
C++FLAGS on $(targets[1]) = ;
get-rspline $(targets) : -TC ;
preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
}
rule compile.c.pch ( targets + : sources * : properties * )
{
C++FLAGS on $(targets[1]) = ;
@@ -363,6 +371,11 @@ actions compile-c-c++ bind PDB_NAME
$(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
}
actions preprocess-c-c++ bind PDB_NAME
{
$(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)"
}
rule compile-c-c++ ( targets + : sources * )
{
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
@@ -370,6 +383,13 @@ rule compile-c-c++ ( targets + : sources * )
PDB_NAME on $(<) = $(<:S=.pdb) ;
}
rule preprocess-c-c++ ( targets + : sources * )
{
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
PDB_NAME on $(<) = $(<:S=.pdb) ;
}
# Action for running the C/C++ compiler using precompiled headers. In addition
# to whatever else it needs to compile, this action also adds a temporary source
# .cpp file used to compile the precompiled headers themselves.
@@ -397,6 +417,12 @@ rule compile.c++ ( targets + : sources * : properties * )
compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
}
rule compile.c++.preprocess ( targets + : sources * : properties * )
{
get-rspline $(targets) : -TP ;
preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
}
rule compile.c++.pch ( targets + : sources * : properties * )
{
@@ -1110,6 +1136,8 @@ local rule register-toolset-really ( )
generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ;
# Using 'register-c-compiler' adds the build directory to INCLUDES.
generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;

View File

@@ -0,0 +1,9 @@
# Copyright Steven Watanabe 2011
# Distributed under the Boost Software License Version 1.0. (See
# accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
import type ;
type.register PREPROCESSED_C : i : C ;
type.register PREPROCESSED_CPP : ii : CPP ;