diff --git a/doc/src/reference.xml b/doc/src/reference.xml index 7e4c4ec86e..058dd377fe 100644 --- a/doc/src/reference.xml +++ b/doc/src/reference.xml @@ -286,7 +286,11 @@ path-constant DATA : data/a.txt ; This rule is deprecated and equivalent to alias. + + outline + Reads the outline of a binary and writes it into the file. + @@ -975,7 +979,20 @@ using gcc : &toolset_ops; ; or rc for borland's resource compiler. + + linker-script + + Specifies a linker script to be used for linking. Several are allowed and each file must have the extension .ld + + + + demangle + + + Can be used to enable demangled when reading the outline. + + 64-bit compilation diff --git a/src/tools/gcc.jam b/src/tools/gcc.jam index 0f346a5015..f60a39f68b 100644 --- a/src/tools/gcc.jam +++ b/src/tools/gcc.jam @@ -49,6 +49,15 @@ type.set-generated-target-suffix OBJ : gcc : o ; type.set-generated-target-suffix OBJ : gcc windows : o ; type.set-generated-target-suffix OBJ : gcc cygwin : o ; +# Add Gnu linker scripts +feature.feature linker-script : : free dependency ; +type.register LINKERSCRIPT : ld : gcc ; + +# Add the size +type.register SIZE ; +type.register HEX : hex ; + + # Initializes the gcc toolset for the given version. If necessary, command may # be used to specify where the compiler is located. The parameter 'options' is a @@ -272,6 +281,46 @@ rule init ( version ? : command * : options * ) rc-type = null ; } rc.configure $(rc) : $(condition) : $(rc-type) ; + + # NM, fg read + local nm = [ common.get-invocation-command gcc + : [ .get-prog-name $(command-string) : nm : $(flavor) ] + : [ feature.get-values : $(options) ] + : $(bin) + : search-path ] ; + + if ! $(nm) + { + $(nm) = nm ; + } + toolset.flags gcc.outline .NM $(condition) : $(nm) ; + + # Objsize create hexfile + local size = [ common.get-invocation-command gcc + : [ .get-prog-name $(command-string) : size : $(flavor) ] + : [ feature.get-values : $(options) ] + : $(bin) + : search-path ] ; + + if ! $(size) + { + $(size) = size ; + } + toolset.flags gcc.objsize .SIZE $(condition) : $(size) ; + + # Objcopy, create hexfile + local objcopy = [ common.get-invocation-command gcc + : [ .get-prog-name $(command-string) : objcopy : $(flavor) ] + : [ feature.get-values : $(options) ] + : $(bin) + : search-path ] ; + + if ! $(objcopy) + { + $(objcopy) = objcopy ; + } + toolset.flags gcc.objcopy .OBJCOPY $(condition) : $(objcopy) ; + toolset.flags gcc.objcopy .SIZE $(condition) : $(size) ; } if [ os.name ] = NT @@ -302,6 +351,10 @@ generators.register-c-compiler gcc.compile.c : C : OBJ : gcc ; generators.register-c-compiler gcc.compile.asm : ASM : OBJ : gcc ; generators.register-fortran-compiler gcc.compile.fortran : FORTRAN FORTRAN90 : OBJ : gcc ; + +generators.register-standard gcc.objcopy : EXE : HEX : gcc ; +generators.register-standard gcc.objsize : EXE : SIZE : gcc ; + # pch support # The compiler looks for a precompiled header in each directory just before it @@ -668,6 +721,7 @@ class gcc-linking-generator : unix-linking-generator } local properties = [ $(property-set).raw ] ; + local reason ; if $(no-static-link) && static in $(properties) { @@ -689,6 +743,7 @@ class gcc-linking-generator : unix-linking-generator } } } + if $(reason) { ECHO warning: $(reason) ; @@ -701,6 +756,20 @@ class gcc-linking-generator : unix-linking-generator $(property-set) : $(sources) ] ; } } + rule generated-targets ( sources + : property-set : project name ? ) + { + # get all the linker-scripts + local .linker-scripts = [ $(property-set).get ] ; + for local ld in $(.linker-scripts) + { + # and now add them as linkflags + local tmp = [ $(ld).name ] ; + property-set = [ $(property-set).add-raw -T$(tmp) $(ld) ] ; + } + + + return [ unix-linking-generator.generated-targets $(sources) : $(property-set) : $(project) $(name) ] ; + } } # The set of permissible input types is different on mingw. So, define two sets @@ -1080,6 +1149,26 @@ local rule cpu-flags ( toolset variable : architecture : instruction-set + : } + +# Outline +actions outline { + $(.NM) $(DEMANGLE) $(>:T) > $(<:T) +} + + +# Objcopy +actions objcopy +{ + $(.OBJCOPY) ./$(>:T) ./$(<:T) + $(.SIZE) ./$(>:T) +} + +# Obj size +actions objsize +{ + $(.SIZE) ./$(>:T) > ./$(<:T) +} + # Set architecture/instruction-set options. # # x86 and compatible diff --git a/src/tools/msvc.jam b/src/tools/msvc.jam index 3f8f49e68b..e0f7a1951a 100644 --- a/src/tools/msvc.jam +++ b/src/tools/msvc.jam @@ -111,6 +111,7 @@ rule init ( # # # + # # # # @@ -501,6 +502,10 @@ actions compile.rc $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)" } +actions outline +{ + $(.DUMPBIN) $(>:W) /RELOCATIONS > $(<:W) +} rule link ( targets + : sources * : properties * ) { @@ -1132,9 +1137,14 @@ local rule configure-really ( version ? : options * ) manifest-tool = [ feature.get-values : $(options) ] ; manifest-tool ?= mt ; + dumpbin = [ feature.get-values : $(options) ] ; + dumpbin ?= dumpbin ; + local cc-filter = [ feature.get-values : $(options) ] ; + + for local c in $(cpu) { # Setup script is not required in some configurations. @@ -1157,6 +1167,7 @@ local rule configure-really ( version ? : options * ) toolset.flags msvc.compile .IDL $(api)/$(cpu-conditions) : $(setup-$(c))$(idl-compiler) ; toolset.flags msvc.compile .MC $(api)/$(cpu-conditions) : $(setup-$(c))$(mc-compiler) ; toolset.flags msvc.link .MT $(api)/$(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ; + toolset.flags msvc.outline .DUMPBIN $(api)/$(cpu-conditions) : $(setup-$(c))$(dumpbin) ; for api in desktop store phone { @@ -1389,6 +1400,8 @@ local rule register-toolset-really ( ) generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : on msvc ] ; generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : on msvc ] ; + generators.register-composing msvc.outline : LIB OBJ EXE : OUTLINE : msvc ; + generators.override msvc.compile.c.pch : pch.default-c-pch-generator ; generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ; } diff --git a/src/tools/types/outline.jam b/src/tools/types/outline.jam new file mode 100644 index 0000000000..d630c2cf4c --- /dev/null +++ b/src/tools/types/outline.jam @@ -0,0 +1,8 @@ +# Copyright Klemens D. Morgenstern 2016. 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 OUTLINE ; + diff --git a/src/tools/unix.jam b/src/tools/unix.jam index 75949851a0..adc01e5096 100644 --- a/src/tools/unix.jam +++ b/src/tools/unix.jam @@ -15,6 +15,14 @@ import type ; import set ; import order ; import builtin ; +import toolset ; + + +# used for nm +feature.feature demangle : off on : propagated ; + + +toolset.flags unix.outline DEMANGLE on : --demangle ; class unix-linking-generator : linking-generator { @@ -155,6 +163,9 @@ generators.register [ new unix-searched-lib-generator unix.searched-lib-generator : : SEARCHED_LIB : unix ] ; +generators.register-composing unix.outline : LIB EXE OBJ : OUTLINE : unix ; + + # The derived toolset must specify their own actions. actions link { } @@ -171,7 +182,10 @@ actions searched-lib-generator { actions prebuilt { } - +# simple implementation here, because clang also uses nm. +actions outline { + nm $(DEMANGLE) $(>:T) > $(<:T) +} diff --git a/test/gcc_runtime.py b/test/gcc_runtime.py index bc56eae9fd..9e0707d707 100644 --- a/test/gcc_runtime.py +++ b/test/gcc_runtime.py @@ -11,8 +11,11 @@ import BoostBuild t = BoostBuild.Tester() -t.write("jamroot.jam", "lib hello : hello.cpp ;") -t.write("hello.cpp", "int main() {}\n") +t.write("jamroot.jam", "exe hello : hello.cpp ; outline mangled : hello ;") +t.write("hello.cpp", "extern \"C\" int i; int main() { i = 42; return 0;}\n") +t.write("script.ld", "i = 42") + +# Also testing linker-scripts. If that thing works, the extern "C" int i can be resolved, elsewise not. t.run_build_system(["runtime-link=static"]) t.expect_output_lines("warning: On gcc, DLLs can not be built with "