From 610b8f1266108462c3e87b8e82e8cc14204d3f76 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 17 Jan 2022 12:50:38 -0500 Subject: [PATCH] Add Size builder - close #143 --- build_tests/simple/size.rb | 6 +++++ doc/user_guide.md | 15 ++++++++++++ lib/rscons.rb | 2 ++ lib/rscons/builders/size.rb | 24 ++++++++++++++++++++ lib/rscons/default_construction_variables.rb | 3 +++ spec/build_tests_spec.rb | 15 ++++++++++++ 6 files changed, 65 insertions(+) create mode 100644 build_tests/simple/size.rb create mode 100644 lib/rscons/builders/size.rb diff --git a/build_tests/simple/size.rb b/build_tests/simple/size.rb new file mode 100644 index 0000000..cf978f0 --- /dev/null +++ b/build_tests/simple/size.rb @@ -0,0 +1,6 @@ +build do + Environment.new do |env| + env.Program("simple.exe", glob("*.c")) + env.Size("simple.size", "simple.exe") + end +end diff --git a/doc/user_guide.md b/doc/user_guide.md index 0a4da54..6c71b7b 100644 --- a/doc/user_guide.md +++ b/doc/user_guide.md @@ -625,6 +625,7 @@ There are several default builders that are built-in to Rscons: library. * `SharedObject`, which compiles source files to produce an object file, in a way that is able to be used to create a shared library. + * `Size`, which runs the 'size' utility on an executable file. ####> The Command Builder @@ -840,6 +841,20 @@ allows it to be used to create a shared library are added. Although it can be called explicitly, it is more commonly implicitly called by the `SharedLibrary` builder. +####> The Size Builder + +```ruby +env.Size(target, sources) +# Example +env.Program("program.exe", glob("*.c")) +env.Size("program.size", "program.exe") +``` + +The `Size` builder runs the "size" executable on the given source file and +stores its output in the target file. +The size executable can be specified with the `SIZE` construction variable, +and flags can be specified with `SIZEFLAGS`. + ###> Phony Targets rscons supports phony build targets. diff --git a/lib/rscons.rb b/lib/rscons.rb index eb9b4f3..fd70a72 100644 --- a/lib/rscons.rb +++ b/lib/rscons.rb @@ -33,6 +33,7 @@ module Rscons :Program, :SharedLibrary, :SharedObject, + :Size, ] # Class to represent a fatal error during an Rscons operation. @@ -146,6 +147,7 @@ require_relative "rscons/builders/program" require_relative "rscons/builders/shared_library" require_relative "rscons/builders/shared_object" require_relative "rscons/builders/simple_builder" +require_relative "rscons/builders/size" # language support require_relative "rscons/builders/lang/asm" diff --git a/lib/rscons/builders/size.rb b/lib/rscons/builders/size.rb new file mode 100644 index 0000000..169b588 --- /dev/null +++ b/lib/rscons/builders/size.rb @@ -0,0 +1,24 @@ +module Rscons + module Builders + # Run the "size" utility on an executable and store its results in the + # target file. + # input file. + # + # Examples:: + # env.Size("^/project.size", "^/project.elf") + class Size < Builder + + # Run the builder to produce a build target. + def run(options) + if @command + finalize_command + else + @vars["_SOURCES"] = @sources + command = @env.build_command("${SIZECMD}", @vars) + standard_command("Size #{Util.short_format_paths(@sources)} => #{@target}", command, stdout: @target) + end + end + + end + end +end diff --git a/lib/rscons/default_construction_variables.rb b/lib/rscons/default_construction_variables.rb index be99196..cf0df52 100644 --- a/lib/rscons/default_construction_variables.rb +++ b/lib/rscons/default_construction_variables.rb @@ -80,6 +80,9 @@ module Rscons "SHLIBLINKPREFIX" => "-l", "SHLIBPREFIX" => on_windows ? "" : "lib", "SHLIBSUFFIX" => on_windows ? ".dll" : ".so", + "SIZE" => "size", + "SIZECMD" => %w[${SIZE} ${SIZEFLAGS} ${_SOURCES}], + "SIZEFLAGS" => [], "YACC" => "bison", "YACCSUFFIX" => %w[.y .yy], "YACC_CMD" => %w[${YACC} ${YACC_FLAGS} -o ${_TARGET} ${_SOURCES}], diff --git a/spec/build_tests_spec.rb b/spec/build_tests_spec.rb index cf77aa9..b69b919 100644 --- a/spec/build_tests_spec.rb +++ b/spec/build_tests_spec.rb @@ -1672,6 +1672,21 @@ EOF end end + context "Size builder" do + it "generates a size file" do + test_dir "simple" + + result = run_rscons(rsconscript: "size.rb") + verify_lines(lines(result.stdout), [ + /Linking .*simple\.exe/, + /Size .*simple\.exe .*simple\.size/, + ]) + expect(File.exist?("simple.exe")).to be_truthy + expect(File.exist?("simple.size")).to be_truthy + expect(File.read("simple.size")).to match /text.*data.*bss/ + end + end + context "multi-threading" do it "waits for subcommands in threads for builders that support threaded commands" do test_dir("simple")