From 6fa4a8556ac115a8ffb6d2e33b6d5bed0e630f6c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 3 Aug 2013 14:47:41 -0400 Subject: [PATCH] support compiling C++ objects with Object builder --- build_tests/simple_cc/build.rb | 4 ++++ build_tests/simple_cc/simple.cc | 8 ++++++++ lib/rscons/builders/object.rb | 16 +++++++++++++--- lib/rscons/builders/program.rb | 16 ++++++++++------ lib/rscons/environment.rb | 8 ++++++++ spec/build_tests_spec.rb | 7 +++++++ 6 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 build_tests/simple_cc/build.rb create mode 100644 build_tests/simple_cc/simple.cc diff --git a/build_tests/simple_cc/build.rb b/build_tests/simple_cc/build.rb new file mode 100644 index 0000000..1ee79f8 --- /dev/null +++ b/build_tests/simple_cc/build.rb @@ -0,0 +1,4 @@ +Rscons::Environment.new do |env| + # CHANGE FLAGS + env.Program('simple', Dir['*.cc']) +end diff --git a/build_tests/simple_cc/simple.cc b/build_tests/simple_cc/simple.cc new file mode 100644 index 0000000..27a31e3 --- /dev/null +++ b/build_tests/simple_cc/simple.cc @@ -0,0 +1,8 @@ +#include + +using namespace std; + +int main(int argc, char *argv[]) +{ + cout << "This is a simple C++ program" << endl; +} diff --git a/lib/rscons/builders/object.rb b/lib/rscons/builders/object.rb index f233f3a..592b5a4 100644 --- a/lib/rscons/builders/object.rb +++ b/lib/rscons/builders/object.rb @@ -12,20 +12,28 @@ module Rscons 'ASDEPGEN' => ['-MMD', '-MF', '$DEPFILE'], 'ASCOM' => ['$AS', '-c', '-o', '$TARGET', '$ASDEPGEN', '-I$[ASPPPATH]', '$ASPPFLAGS', '$ASFLAGS', '$SOURCES'], - 'CC' => 'gcc', - 'CFLAGS' => [], 'CPPFLAGS' => [], 'CPPPATH' => [], + + 'CC' => 'gcc', + 'CFLAGS' => [], 'CSUFFIX' => '.c', 'CCDEPGEN' => ['-MMD', '-MF', '$DEPFILE'], 'CCCOM' => ['$CC', '-c', '-o', '$TARGET', '$CCDEPGEN', '-I$[CPPPATH]', '$CPPFLAGS', '$CFLAGS', '$SOURCES'], + + 'CXX' => 'g++', + 'CXXFLAGS' => [], + 'CXXSUFFIX' => '.cc', + 'CXXDEPGEN' => ['-MMD', '-MF', '$DEPFILE'], + 'CXXCOM' =>['$CXX', '-c', '-o', '$TARGET', '$CXXDEPGEN', '-I$[CPPPATH]', '$CPPFLAGS', '$CXXFLAGS', '$SOURCES'], } end def produces?(target, source, env) target.has_suffix?(env['OBJSUFFIX']) and ( source.has_suffix?(env['ASSUFFIX']) or - source.has_suffix?(env['CSUFFIX'])) + source.has_suffix?(env['CSUFFIX']) or + source.has_suffix?(env['CXXSUFFIX'])) end def run(target, sources, cache, env) @@ -38,6 +46,8 @@ module Rscons 'AS' elsif sources.first.has_suffix?(env['CSUFFIX']) 'CC' + elsif sources.first.has_suffix?(env['CXXSUFFIX']) + 'CXX' else raise "Error: unknown input file type: #{sources.first.inspect}" end diff --git a/lib/rscons/builders/program.rb b/lib/rscons/builders/program.rb index ff1f084..48933b9 100644 --- a/lib/rscons/builders/program.rb +++ b/lib/rscons/builders/program.rb @@ -14,7 +14,7 @@ module Rscons def run(target, sources, cache, env) # convert sources to object file names - sources = sources.map do |source| + objects = sources.map do |source| if source.has_suffix?([env['OBJSUFFIX'], env['LIBSUFFIX']]) source else @@ -24,16 +24,20 @@ module Rscons builder.run(o_file, [source], cache, env) or break end end - if sources + if objects + use_cxx = sources.map do |s| + s.has_suffix?(env['CXXSUFFIX']) + end.any? + ld_alt = use_cxx ? env['CXX'] : env['CC'] vars = { 'TARGET' => target, - 'SOURCES' => sources, - 'LD' => env['LD'] || env['CC'], # TODO: figure out whether to use CC or CXX + 'SOURCES' => objects, + 'LD' => env['LD'] || ld_alt, } command = env.build_command(env['LDCOM'], vars) - unless cache.up_to_date?(target, command, sources) + unless cache.up_to_date?(target, command, objects) return false unless env.execute("LD #{target}", command) - cache.register_build(target, command, sources) + cache.register_build(target, command, objects) end target end diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index 064c69c..ede0b2e 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -89,6 +89,14 @@ module Rscons @varset.send(:append, *args) end + def targets + @targets.keys + end + + def target_sources(target) + @targets[target][:source] rescue nil + end + def process cache = Cache.new targets_processed = Set.new diff --git a/spec/build_tests_spec.rb b/spec/build_tests_spec.rb index 6b79dab..d74244a 100644 --- a/spec/build_tests_spec.rb +++ b/spec/build_tests_spec.rb @@ -136,4 +136,11 @@ describe Rscons do %q{gcc -o program-release release/program.o}, ] end + + it 'builds a C++ program with one source file' do + test_dir('simple_cc') + File.exists?('simple.o').should be_true + `./simple`.should == "This is a simple C++ program\n" + end + end