From 3ab5bb78c8ca2d71d9902dab34209670eac341af Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 7 May 2013 21:07:56 +0300 Subject: [PATCH 01/16] Update comments to reflect the new roles of classes --- source/builder.h | 4 ++-- source/buildercli.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/builder.h b/source/builder.h index aef0f47..4c78a3d 100644 --- a/source/builder.h +++ b/source/builder.h @@ -22,8 +22,8 @@ class Package; class SourcePackage; /** -The main application class. Handles command line options and supervises the -build process. +This class ties everything else together. It also contains code for loading +build files and supervising the build process. */ class Builder { diff --git a/source/buildercli.h b/source/buildercli.h index 42ed0c3..f9d7ee2 100644 --- a/source/buildercli.h +++ b/source/buildercli.h @@ -6,6 +6,9 @@ class Analyzer; +/** +Provides a command-line interface for Builder. +*/ class BuilderCLI: public Msp::RegisteredApplication { private: -- 2.43.0 From 28bc25948ff58612600ce29a6a0b2cf58548dff9 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 7 May 2013 21:21:38 +0300 Subject: [PATCH 02/16] Resolve cmdline targets and what-ifs the same way --- source/buildercli.cpp | 17 ++++++++++------- source/buildercli.h | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/source/buildercli.cpp b/source/buildercli.cpp index 0bdf877..35eba9c 100644 --- a/source/buildercli.cpp +++ b/source/buildercli.cpp @@ -279,18 +279,13 @@ bool BuilderCLI::prepare_build() during preparation. */ BuildGraph &build_graph = builder.get_build_graph(); PackageManager &package_manager = builder.get_package_manager(); - VirtualFileSystem &vfs = builder.get_vfs(); package_manager.get_main_package().prepare(); // Add targets from command line as goals for(NameList::iterator i=cmdline_targets.begin(); i!=cmdline_targets.end(); ++i) { - Target *tgt = build_graph.get_target(*i); - if(!tgt) - tgt = vfs.get_target(*i); - if(!tgt) - tgt = vfs.get_target(cwd/ *i); + Target *tgt = resolve_target(*i); if(!tgt) { IO::print("I don't know anything about %s\n", *i); @@ -305,7 +300,7 @@ bool BuilderCLI::prepare_build() // Apply what-ifs for(NameList::iterator i=what_if.begin(); i!=what_if.end(); ++i) { - FileTarget *tgt = vfs.get_target(cwd/ *i); + FileTarget *tgt = dynamic_cast(resolve_target(*i)); if(!tgt) { IO::print(IO::cerr, "Unknown what-if target %s\n", *i); @@ -327,6 +322,14 @@ bool BuilderCLI::prepare_build() return true; } +Target *BuilderCLI::resolve_target(const string &name) +{ + Target *tgt = builder.get_build_graph().get_target(name); + if(!tgt) + tgt = builder.get_vfs().get_target(cwd/name); + return tgt; +} + void BuilderCLI::package_help() { PackageManager &package_manager = builder.get_package_manager(); diff --git a/source/buildercli.h b/source/buildercli.h index f9d7ee2..efc2cc9 100644 --- a/source/buildercli.h +++ b/source/buildercli.h @@ -43,6 +43,7 @@ public: private: bool prepare_build(); + Target *resolve_target(const std::string &); void package_help(); }; -- 2.43.0 From cb286fd20b9b194947b6b583bf18f8d7e57ae995 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 7 May 2013 21:42:39 +0300 Subject: [PATCH 03/16] Properly process the command line arguments --- source/buildercli.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/buildercli.cpp b/source/buildercli.cpp index 35eba9c..c470f04 100644 --- a/source/buildercli.cpp +++ b/source/buildercli.cpp @@ -121,14 +121,16 @@ BuilderCLI::BuilderCLI(int argc, char **argv): else if(!clean && !create_makefile) build = true; - const vector &args = getopt.get_args(); - for(vector::const_iterator i=args.begin(); i!=args.end(); ++i) + for(NameList::iterator i=cmdline_targets.begin(); i!=cmdline_targets.end(); ) { string::size_type equal = i->find('='); if(equal!=string::npos) + { cmdline_options.insert(Config::InputOptions::value_type(i->substr(0, equal), i->substr(equal+1))); + cmdline_targets.erase(i++); + } else - cmdline_targets.push_back(*i); + ++i; } if(!work_dir.empty()) -- 2.43.0 From d6d1d6ef8f589747b996f223c6c65dd293fedd93 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 7 May 2013 21:43:11 +0300 Subject: [PATCH 04/16] Add a convenience function for saving caches in PackageManager --- source/buildercli.cpp | 6 +----- source/packagemanager.cpp | 6 ++++++ source/packagemanager.h | 3 +++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/source/buildercli.cpp b/source/buildercli.cpp index c470f04..6292318 100644 --- a/source/buildercli.cpp +++ b/source/buildercli.cpp @@ -315,11 +315,7 @@ bool BuilderCLI::prepare_build() build_graph.force_full_rebuild(); if(!dry_run) - { - const PackageManager::PackageMap &packages = package_manager.get_packages(); - for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) - i->second->save_caches(); - } + package_manager.save_all_caches(); return true; } diff --git a/source/packagemanager.cpp b/source/packagemanager.cpp index f840ea2..0e2d8a0 100644 --- a/source/packagemanager.cpp +++ b/source/packagemanager.cpp @@ -244,3 +244,9 @@ FS::Path PackageManager::get_binary_package_file(const string &name) return FS::Path(); } + +void PackageManager::save_all_caches() const +{ + for(PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) + i->second->save_caches(); +} diff --git a/source/packagemanager.h b/source/packagemanager.h index 9b4f347..b168d72 100644 --- a/source/packagemanager.h +++ b/source/packagemanager.h @@ -71,6 +71,9 @@ private: /** Determines the file containing a binary package. The file is expected to be named after the package. */ Msp::FS::Path get_binary_package_file(const std::string &); + +public: + void save_all_caches() const; }; #endif -- 2.43.0 From fa2beaa15ccc64956b12d6d81d95a11538748327 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 7 May 2013 23:40:30 +0300 Subject: [PATCH 05/16] Target::build is virtual, so put the special case in the appropriate class --- source/target.cpp | 7 ------- source/virtualtarget.cpp | 6 ++++++ source/virtualtarget.h | 3 +++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source/target.cpp b/source/target.cpp index 691f700..a9ad8e7 100644 --- a/source/target.cpp +++ b/source/target.cpp @@ -122,13 +122,6 @@ void Target::prepare() Task *Target::build() { - if(!tool) - { - // This special case is needed for VirtualTargets - state = UPTODATE; - return 0; - } - Task *task = tool->run(*this); task->signal_finished.connect(sigc::mem_fun(this, &Target::build_finished)); state = BUILDING; diff --git a/source/virtualtarget.cpp b/source/virtualtarget.cpp index 3a3b254..a7b4cd7 100644 --- a/source/virtualtarget.cpp +++ b/source/virtualtarget.cpp @@ -17,3 +17,9 @@ void VirtualTarget::check_rebuild() if((*i)->needs_rebuild()) mark_rebuild((*i)->get_name()+" needs rebuilding"); } + +Task *VirtualTarget::build() +{ + state = UPTODATE; + return 0; +} diff --git a/source/virtualtarget.h b/source/virtualtarget.h index bd39e5f..8f3d95b 100644 --- a/source/virtualtarget.h +++ b/source/virtualtarget.h @@ -14,6 +14,9 @@ public: virtual const char *get_type() const { return "VirtualTarget"; } private: virtual void check_rebuild(); + +public: + virtual Task *build(); }; #endif -- 2.43.0 From 9e28243c9687608ec3c32954b4031490296ae877 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 8 May 2013 10:24:45 +0300 Subject: [PATCH 06/16] Delay locating tool executables until the tool is needed This solves a problem where the mspdatatool executable is not detected as built by the mspdatafile package. --- source/component.cpp | 12 ++++---- source/copy.cpp | 2 +- source/copy.h | 2 +- source/datatool.cpp | 13 +++++---- source/datatool.h | 5 +++- source/gnuarchiver.cpp | 15 ++++++---- source/gnuarchiver.h | 5 +++- source/gnucompiler.cpp | 21 +++++++------ source/gnucompiler.h | 8 ++++- source/gnucxxcompiler.cpp | 10 +++++-- source/gnucxxcompiler.h | 3 ++ source/gnulinker.cpp | 55 ++++++++++++++++++++--------------- source/gnulinker.h | 10 +++++-- source/mingwdlltool.cpp | 19 +++++++----- source/mingwdlltool.h | 6 +++- source/pkgconfiggenerator.cpp | 2 +- source/pkgconfiggenerator.h | 2 +- source/tar.cpp | 2 +- source/tar.h | 2 +- source/target.cpp | 6 ++-- source/target.h | 4 +-- source/tool.cpp | 17 +++++++++-- source/tool.h | 12 ++++++-- source/toolchain.cpp | 4 +-- source/toolchain.h | 4 +-- 25 files changed, 153 insertions(+), 88 deletions(-) diff --git a/source/component.cpp b/source/component.cpp index 371e145..d0cc1e9 100644 --- a/source/component.cpp +++ b/source/component.cpp @@ -138,7 +138,7 @@ void Component::create_targets() const string inst_loc; if(type==TARBALL) { - const Tool &tar = toolchain.get_tool("TAR"); + Tool &tar = toolchain.get_tool("TAR"); list files; for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) @@ -171,7 +171,7 @@ void Component::create_targets() const else if(type==INSTALL) { Target *inst = build_graph.get_target("install"); - const Tool © = toolchain.get_tool("CP"); + Tool © = toolchain.get_tool("CP"); for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) { FileTarget *ft; @@ -184,7 +184,7 @@ void Component::create_targets() const } else if(type==DATAPACK) { - const Tool &dcomp = toolchain.get_tool("DATA"); + Tool &dcomp = toolchain.get_tool("DATA"); list files; for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) @@ -214,7 +214,7 @@ void Component::create_targets() const for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i) { string ext = FS::extpart(FS::basename(*i)); - const Tool *tool = toolchain.get_tool_for_suffix(ext, true); + Tool *tool = toolchain.get_tool_for_suffix(ext, true); if(tool) { Target *src = tool->create_source(*this, *i); @@ -232,12 +232,12 @@ void Component::create_targets() const } } - const Tool &linker = toolchain.get_tool("LINK"); + Tool &linker = toolchain.get_tool("LINK"); list results; if(type==LIBRARY) { - const Tool &archiver = toolchain.get_tool("AR"); + Tool &archiver = toolchain.get_tool("AR"); results.push_back(linker.create_target(objs, "shared")); results.push_back(archiver.create_target(objs)); } diff --git a/source/copy.cpp b/source/copy.cpp index 75d047d..24be942 100644 --- a/source/copy.cpp +++ b/source/copy.cpp @@ -16,7 +16,7 @@ Copy::Copy(Builder &b): Tool(b, "CP") { } -Target *Copy::create_target(const list &sources, const string &arg) const +Target *Copy::create_target(const list &sources, const string &arg) { FileTarget &file_tgt = dynamic_cast(*sources.front()); InstalledFile *inst = new InstalledFile(builder, *file_tgt.get_package(), file_tgt, arg); diff --git a/source/copy.h b/source/copy.h index 3aa10a9..dedd0f5 100644 --- a/source/copy.h +++ b/source/copy.h @@ -31,7 +31,7 @@ private: public: Copy(Builder &); - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); virtual Task *run(const Target &) const; }; diff --git a/source/datatool.cpp b/source/datatool.cpp index a956984..4a4fc8a 100644 --- a/source/datatool.cpp +++ b/source/datatool.cpp @@ -16,10 +16,6 @@ using namespace Msp; DataTool::DataTool(Builder &b): Tool(b, "DATA") { - executable = builder.get_vfs().find_binary("mspdatatool"); - if(!executable) - builder.problem(string(), format("Can't find executable mspdatatool for tool %s", tag)); - input_suffixes.push_back(".mdt"); } @@ -28,7 +24,7 @@ Target *DataTool::create_source(const Component &comp, const FS::Path &path) con return new DataTransform(builder, comp, path); } -Target *DataTool::create_target(const list &sources, const string &arg) const +Target *DataTool::create_target(const list &sources, const string &arg) { if(arg=="collection") { @@ -52,6 +48,13 @@ Target *DataTool::create_target(const list &sources, const string &arg throw invalid_argument("DataTool::create_target"); } +void DataTool::do_prepare() +{ + executable = builder.get_vfs().find_binary("mspdatatool"); + if(!executable) + builder.problem(string(), format("Can't find executable mspdatatool for tool %s", tag)); +} + Task *DataTool::run(const Target &tgt) const { const Component &comp = *tgt.get_component(); diff --git a/source/datatool.h b/source/datatool.h index b6c4f5b..f2720c0 100644 --- a/source/datatool.h +++ b/source/datatool.h @@ -9,7 +9,10 @@ public: DataTool(Builder &); virtual Target *create_source(const Component &, const Msp::FS::Path &) const; - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); +private: + virtual void do_prepare(); +public: virtual Task *run(const Target &) const; }; diff --git a/source/gnuarchiver.cpp b/source/gnuarchiver.cpp index 3499204..7482b0d 100644 --- a/source/gnuarchiver.cpp +++ b/source/gnuarchiver.cpp @@ -17,15 +17,10 @@ using namespace Msp; GnuArchiver::GnuArchiver(Builder &b, const Architecture &a): Tool(b, a, "AR") { - string command = "ar"; - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); - input_suffixes.push_back(".o"); } -Target *GnuArchiver::create_target(const list &sources, const string &) const +Target *GnuArchiver::create_target(const list &sources, const string &) { if(sources.empty()) throw invalid_argument("GnuArchiver::create_target"); @@ -45,6 +40,14 @@ Target *GnuArchiver::create_target(const list &sources, const string & return lib; } +void GnuArchiver::do_prepare() +{ + string command = "ar"; + if(architecture->is_cross()) + command = format("%s-%s", architecture->get_cross_prefix(), command); + executable = builder.get_vfs().find_binary(command); +} + Task *GnuArchiver::run(const Target &target) const { const StaticLibrary &lib = dynamic_cast(target); diff --git a/source/gnuarchiver.h b/source/gnuarchiver.h index 41386f6..2c625b6 100644 --- a/source/gnuarchiver.h +++ b/source/gnuarchiver.h @@ -8,7 +8,10 @@ class GnuArchiver: public Tool public: GnuArchiver(Builder &, const Architecture &); - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); +private: + virtual void do_prepare(); +public: virtual Task *run(const Target &) const; }; diff --git a/source/gnucompiler.cpp b/source/gnucompiler.cpp index 06ad5a9..7d1d166 100644 --- a/source/gnucompiler.cpp +++ b/source/gnucompiler.cpp @@ -14,22 +14,16 @@ using namespace std; using namespace Msp; GnuCompiler::GnuCompiler(Builder &b, const Architecture &a, const string &t, const string &c): - Tool(b, a, t) + Tool(b, a, t), + command(c) { - string command = c; - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); - if(!executable) - builder.problem(string(), format("Can't find executable %s for tool %s", command, tag)); - if(architecture->is_native()) system_path.push_back("/usr/include"); else system_path.push_back("/usr/"+architecture->get_cross_prefix()+"/include"); } -Target *GnuCompiler::create_target(const list &sources, const string &) const +Target *GnuCompiler::create_target(const list &sources, const string &) { if(sources.size()!=1) throw invalid_argument("GnuCCompiler::create_target"); @@ -58,6 +52,15 @@ string GnuCompiler::create_build_signature(const BuildInfo &binfo) const return result; } +void GnuCompiler::do_prepare() +{ + if(architecture->is_cross()) + command = format("%s-%s", architecture->get_cross_prefix(), command); + executable = builder.get_vfs().find_binary(command); + if(!executable) + builder.problem(string(), format("Can't find executable %s for tool %s", command, tag)); +} + Task *GnuCompiler::run(const Target &target) const { const ObjectFile &object = dynamic_cast(target); diff --git a/source/gnucompiler.h b/source/gnucompiler.h index 5992876..0c283e2 100644 --- a/source/gnucompiler.h +++ b/source/gnucompiler.h @@ -12,12 +12,18 @@ appropriate type. */ class GnuCompiler: public Tool { +private: + std::string command; + protected: GnuCompiler(Builder &, const Architecture &, const std::string &, const std::string &); public: - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); virtual std::string create_build_signature(const BuildInfo &) const; +protected: + virtual void do_prepare(); +public: virtual Task *run(const Target &) const; }; diff --git a/source/gnucxxcompiler.cpp b/source/gnucxxcompiler.cpp index 9e206cc..1926a5e 100644 --- a/source/gnucxxcompiler.cpp +++ b/source/gnucxxcompiler.cpp @@ -16,9 +16,6 @@ GnuCxxCompiler::GnuCxxCompiler(Builder &b, const Architecture &a): input_suffixes.push_back(".cpp"); input_suffixes.push_back(".cc"); aux_suffixes.push_back(".hpp"); - - if(executable) - query_version(); } void GnuCxxCompiler::query_version() @@ -50,3 +47,10 @@ Target *GnuCxxCompiler::create_source(const FS::Path &path) const { return new CSourceFile(builder, path); } + +void GnuCxxCompiler::do_prepare() +{ + GnuCompiler::do_prepare(); + if(executable) + query_version(); +} diff --git a/source/gnucxxcompiler.h b/source/gnucxxcompiler.h index 314bb51..5cdc34b 100644 --- a/source/gnucxxcompiler.h +++ b/source/gnucxxcompiler.h @@ -16,6 +16,9 @@ private: public: virtual Target *create_source(const Component &, const Msp::FS::Path &) const; virtual Target *create_source(const Msp::FS::Path &) const; + +private: + virtual void do_prepare(); }; #endif diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index 21b765b..cfdee8d 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -49,7 +49,7 @@ GnuLinker::~GnuLinker() delete cxx_linker; } -Target *GnuLinker::create_target(const list &sources, const string &arg) const +Target *GnuLinker::create_target(const list &sources, const string &arg) { if(sources.empty()) throw invalid_argument("GnuLinker::create_target"); @@ -74,7 +74,7 @@ Target *GnuLinker::create_target(const list &sources, const string &ar SharedLibrary *shlib = new SharedLibrary(builder, comp, objs); if(architecture->get_system()=="windows") { - const Tool &dlltool = builder.get_toolchain().get_tool("DLL"); + Tool &dlltool = builder.get_toolchain().get_tool("DLL"); dlltool.create_target(*shlib); } bin = shlib; @@ -89,7 +89,7 @@ Target *GnuLinker::create_install(Target &target) const { if(SharedLibrary *shlib = dynamic_cast(&target)) { - const Tool © = builder.get_toolchain().get_tool("CP"); + Tool © = builder.get_toolchain().get_tool("CP"); InstalledFile *inst_tgt = dynamic_cast(copy.create_target(target)); if(architecture->get_system()=="windows") builder.get_build_graph().add_installed_target(*shlib->get_import_library()); @@ -112,28 +112,12 @@ Task *GnuLinker::run(const Target &) const } -GnuLinker::Linker::Linker(GnuLinker &p, const string &compiler_tag): - SubTool(p) -{ - const Tool &compiler = builder.get_toolchain().get_tool(compiler_tag); - if(dynamic_cast(&compiler)) - executable = compiler.get_executable(); - else - { - string command; - if(compiler_tag=="CC") - command = "gcc"; - else if(compiler_tag=="CXX") - command = "g++"; - else - throw invalid_argument("GnuLinker::Linker::Linker"); - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); - } -} +GnuLinker::Linker::Linker(GnuLinker &p, const string &ct): + SubTool(p), + compiler_tag(ct) +{ } -Target *GnuLinker::Linker::create_target(const list &sources, const string &arg) const +Target *GnuLinker::Linker::create_target(const list &sources, const string &arg) { return parent.create_target(sources, arg); } @@ -158,6 +142,29 @@ string GnuLinker::Linker::create_build_signature(const BuildInfo &binfo) const return result; } +void GnuLinker::Linker::do_prepare() +{ + Tool &compiler = builder.get_toolchain().get_tool(compiler_tag); + if(dynamic_cast(&compiler)) + { + compiler.prepare(); + executable = compiler.get_executable(); + } + else + { + string command; + if(compiler_tag=="CC") + command = "gcc"; + else if(compiler_tag=="CXX") + command = "g++"; + else + throw invalid_argument("GnuLinker::Linker::Linker"); + if(architecture->is_cross()) + command = format("%s-%s", architecture->get_cross_prefix(), command); + executable = builder.get_vfs().find_binary(command); + } +} + Task *GnuLinker::Linker::run(const Target &target) const { const Binary &bin = dynamic_cast(target); diff --git a/source/gnulinker.h b/source/gnulinker.h index 07e6a0c..4673c07 100644 --- a/source/gnulinker.h +++ b/source/gnulinker.h @@ -15,12 +15,18 @@ class GnuLinker: public Tool private: class Linker: public SubTool { + private: + std::string compiler_tag; + public: Linker(GnuLinker &, const std::string &); - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); virtual Target *create_install(Target &) const; virtual std::string create_build_signature(const BuildInfo &) const; + private: + virtual void do_prepare(); + public: virtual Task *run(const Target &) const; }; @@ -31,7 +37,7 @@ public: GnuLinker(Builder &, const Architecture &); ~GnuLinker(); - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); virtual Target *create_install(Target &) const; virtual Task *run(const Target &) const; }; diff --git a/source/mingwdlltool.cpp b/source/mingwdlltool.cpp index 5f62a02..f44f575 100644 --- a/source/mingwdlltool.cpp +++ b/source/mingwdlltool.cpp @@ -18,14 +18,9 @@ using namespace Msp; MingwDllTool::MingwDllTool(Builder &b, const Architecture &a): Tool(b, a, "DLL") -{ - string command = "dlltool"; - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); -} +{ } -Target *MingwDllTool::create_target(const list &sources, const string &) const +Target *MingwDllTool::create_target(const list &sources, const string &) { if(sources.size()!=1) throw invalid_argument("MingwDllTool::create_target"); @@ -50,7 +45,7 @@ Target *MingwDllTool::create_install(Target &target) const { if(ImportLibrary *imp = dynamic_cast(&target)) { - const Tool © = builder.get_toolchain().get_tool("CP"); + Tool © = builder.get_toolchain().get_tool("CP"); InstalledFile *inst_tgt = dynamic_cast(copy.create_target(target)); string link_name = format("lib%s.dll.a", imp->get_shared_library()->get_libname()); if(link_name!=FS::basename(inst_tgt->get_path())) @@ -61,6 +56,14 @@ Target *MingwDllTool::create_install(Target &target) const return 0; } +void MingwDllTool::do_prepare() +{ + string command = "dlltool"; + if(architecture->is_cross()) + command = format("%s-%s", architecture->get_cross_prefix(), command); + executable = builder.get_vfs().find_binary(command); +} + Task *MingwDllTool::run(const Target &target) const { const ImportLibrary *imp = dynamic_cast(&target); diff --git a/source/mingwdlltool.h b/source/mingwdlltool.h index 25a1e10..796da75 100644 --- a/source/mingwdlltool.h +++ b/source/mingwdlltool.h @@ -8,9 +8,13 @@ class MingwDllTool: public Tool public: MingwDllTool(Builder &, const Architecture &); - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); virtual Target *create_install(Target &) const; +private: + virtual void do_prepare(); + +public: virtual Task *run(const Target &) const; }; diff --git a/source/pkgconfiggenerator.cpp b/source/pkgconfiggenerator.cpp index b4ba545..677ef9b 100644 --- a/source/pkgconfiggenerator.cpp +++ b/source/pkgconfiggenerator.cpp @@ -13,7 +13,7 @@ PkgConfigGenerator::PkgConfigGenerator(Builder &b): { } -Target *PkgConfigGenerator::create_target(const list &, const string &) const +Target *PkgConfigGenerator::create_target(const list &, const string &) { throw logic_error("Not implemented"); } diff --git a/source/pkgconfiggenerator.h b/source/pkgconfiggenerator.h index 14ba317..a9adbc6 100644 --- a/source/pkgconfiggenerator.h +++ b/source/pkgconfiggenerator.h @@ -26,7 +26,7 @@ private: public: PkgConfigGenerator(Builder &); - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); virtual Task *run(const Target &) const; }; diff --git a/source/tar.cpp b/source/tar.cpp index ac2f9e8..bcaa852 100644 --- a/source/tar.cpp +++ b/source/tar.cpp @@ -15,7 +15,7 @@ Tar::Tar(Builder &b): Tool(b, "TAR") { } -Target *Tar::create_target(const list &sources, const string &arg) const +Target *Tar::create_target(const list &sources, const string &arg) { if(!sources.front()->get_package()) throw invalid_argument("Tar::create_target"); diff --git a/source/tar.h b/source/tar.h index c11587e..9be26d9 100644 --- a/source/tar.h +++ b/source/tar.h @@ -26,7 +26,7 @@ private: public: Tar(Builder &); - virtual Target *create_target(const std::list &, const std::string &) const; + virtual Target *create_target(const std::list &, const std::string &); virtual Task *run(const Target &) const; }; diff --git a/source/target.cpp b/source/target.cpp index a9ad8e7..87b0d00 100644 --- a/source/target.cpp +++ b/source/target.cpp @@ -64,7 +64,7 @@ Target *Target::get_buildable_target() return 0; } -void Target::set_tool(const Tool &t) +void Target::set_tool(Tool &t) { tool = &t; for(Dependencies::const_iterator i=side_effects.begin(); i!=side_effects.end(); ++i) @@ -102,12 +102,12 @@ void Target::prepare() } state = PREPARING; + if(tool) + tool->prepare(); find_dependencies(); if(tool) - { if(FileTarget *tool_exe = tool->get_executable()) add_dependency(*tool_exe); - } for(Dependencies::iterator i=depends.begin(); i!=depends.end(); ++i) (*i)->prepare(); diff --git a/source/target.h b/source/target.h index 0b9d230..eda77d0 100644 --- a/source/target.h +++ b/source/target.h @@ -42,7 +42,7 @@ protected: const Component *component; std::string name; - const Tool *tool; + Tool *tool; State state; std::string rebuild_reason; @@ -95,7 +95,7 @@ public: the function recursively to find the final target. */ virtual Target *get_real_target() { return this; } - void set_tool(const Tool &); + void set_tool(Tool &); /** Returns the tool used to build the target. To actually build it, call the build() function. */ diff --git a/source/tool.cpp b/source/tool.cpp index cefbb8c..a23de63 100644 --- a/source/tool.cpp +++ b/source/tool.cpp @@ -7,14 +7,16 @@ Tool::Tool(Builder &b, const string &t): builder(b), architecture(0), tag(t), - executable(0) + executable(0), + prepared(false) { } Tool::Tool(Builder &b, const Architecture &a, const string &t): builder(b), architecture(&a), tag(t), - executable(0) + executable(0), + prepared(false) { } bool Tool::accepts_suffix(const string &suffix, bool aux) const @@ -27,13 +29,22 @@ bool Tool::accepts_suffix(const string &suffix, bool aux) const return false; } -Target *Tool::create_target(Target &source, const string &arg) const +Target *Tool::create_target(Target &source, const string &arg) { list sources; sources.push_back(&source); return create_target(sources, arg); } +void Tool::prepare() +{ + if(prepared) + return; + + prepared = true; + do_prepare(); +} + SubTool::SubTool(Tool &p): Tool(p), diff --git a/source/tool.h b/source/tool.h index 2948053..73be90d 100644 --- a/source/tool.h +++ b/source/tool.h @@ -31,6 +31,7 @@ protected: SuffixList input_suffixes; SuffixList aux_suffixes; SearchPath system_path; + bool prepared; Tool(Builder &, const std::string &); Tool(Builder &, const Architecture &, const std::string &); @@ -41,7 +42,6 @@ public: /** Returns a target for the tool's own executable. If the tool does not use an external program, returns null. */ - // XXX The executable target should be retrieved when first needed FileTarget *get_executable() const { return executable; } /// Returns a list of suffixes that can be processed with this tool. @@ -67,12 +67,12 @@ public: virtual Target *create_source(const Msp::FS::Path &) const { return 0; } /// Convenience function to create a target from a single source. - Target *create_target(Target &, const std::string & = std::string()) const; + Target *create_target(Target &, const std::string & = std::string()); /** Creates a target from sources. The exact types of accepted sources depends on the tool. The optional second argument can be used to select an alternative target type for tools that can create multiple kinds of targets. */ - virtual Target *create_target(const std::list &, const std::string & = std::string()) const = 0; + virtual Target *create_target(const std::list &, const std::string & = std::string()) = 0; /** Creates an install target for a target created by this tool. Can return null if the tool does not want to handle installing in a special way. */ @@ -80,6 +80,12 @@ public: virtual std::string create_build_signature(const BuildInfo &) const { return std::string(); } + void prepare(); + +protected: + virtual void do_prepare() { } + +public: /** Invokes the tool to build a target. This should not be called directly; use Target::build() instead. */ virtual Task *run(const Target &) const = 0; diff --git a/source/toolchain.cpp b/source/toolchain.cpp index cdbc7aa..9d23403 100644 --- a/source/toolchain.cpp +++ b/source/toolchain.cpp @@ -16,12 +16,12 @@ void Toolchain::add_tool(Tool *tool) insert_unique(tools, tool->get_tag(), tool); } -const Tool &Toolchain::get_tool(const string &tag) const +Tool &Toolchain::get_tool(const string &tag) const { return *get_item(tools, tag); } -const Tool *Toolchain::get_tool_for_suffix(const string &suffix, bool aux) const +Tool *Toolchain::get_tool_for_suffix(const string &suffix, bool aux) const { for(ToolMap::const_iterator i=tools.begin(); i!=tools.end(); ++i) if(i->second->accepts_suffix(suffix, aux)) diff --git a/source/toolchain.h b/source/toolchain.h index 2c0e3d2..572e42f 100644 --- a/source/toolchain.h +++ b/source/toolchain.h @@ -20,8 +20,8 @@ public: ~Toolchain(); void add_tool(Tool *); - const Tool &get_tool(const std::string &) const; - const Tool *get_tool_for_suffix(const std::string &, bool = false) const; + Tool &get_tool(const std::string &) const; + Tool *get_tool_for_suffix(const std::string &, bool = false) const; }; #endif -- 2.43.0 From 7ed7c30ee0ceb734f17fe0c6d4bc6d37fb2ab5a7 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 8 May 2013 11:16:36 +0300 Subject: [PATCH 07/16] Add a utility function for setting the executable for a Tool --- source/datatool.cpp | 5 +---- source/gnuarchiver.cpp | 6 +----- source/gnucompiler.cpp | 6 +----- source/gnulinker.cpp | 5 ++--- source/mingwdlltool.cpp | 6 +----- source/tool.cpp | 14 ++++++++++++++ source/tool.h | 5 +++++ 7 files changed, 25 insertions(+), 22 deletions(-) diff --git a/source/datatool.cpp b/source/datatool.cpp index 4a4fc8a..eeeec4e 100644 --- a/source/datatool.cpp +++ b/source/datatool.cpp @@ -1,6 +1,5 @@ #include #include -#include #include "builder.h" #include "component.h" #include "datacollection.h" @@ -50,9 +49,7 @@ Target *DataTool::create_target(const list &sources, const string &arg void DataTool::do_prepare() { - executable = builder.get_vfs().find_binary("mspdatatool"); - if(!executable) - builder.problem(string(), format("Can't find executable mspdatatool for tool %s", tag)); + set_executable("mspdatatool"); } Task *DataTool::run(const Target &tgt) const diff --git a/source/gnuarchiver.cpp b/source/gnuarchiver.cpp index 7482b0d..cc4359e 100644 --- a/source/gnuarchiver.cpp +++ b/source/gnuarchiver.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "builder.h" #include "component.h" @@ -42,10 +41,7 @@ Target *GnuArchiver::create_target(const list &sources, const string & void GnuArchiver::do_prepare() { - string command = "ar"; - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); + set_executable("ar", true); } Task *GnuArchiver::run(const Target &target) const diff --git a/source/gnucompiler.cpp b/source/gnucompiler.cpp index 7d1d166..ec1959a 100644 --- a/source/gnucompiler.cpp +++ b/source/gnucompiler.cpp @@ -54,11 +54,7 @@ string GnuCompiler::create_build_signature(const BuildInfo &binfo) const void GnuCompiler::do_prepare() { - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); - if(!executable) - builder.problem(string(), format("Can't find executable %s for tool %s", command, tag)); + set_executable(command, true); } Task *GnuCompiler::run(const Target &target) const diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index cfdee8d..02708cc 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -159,9 +159,8 @@ void GnuLinker::Linker::do_prepare() command = "g++"; else throw invalid_argument("GnuLinker::Linker::Linker"); - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); + + set_executable(command, true); } } diff --git a/source/mingwdlltool.cpp b/source/mingwdlltool.cpp index f44f575..1bb3509 100644 --- a/source/mingwdlltool.cpp +++ b/source/mingwdlltool.cpp @@ -1,7 +1,6 @@ #include #include #include -#include "architecture.h" #include "builder.h" #include "component.h" #include "exportdefinitions.h" @@ -58,10 +57,7 @@ Target *MingwDllTool::create_install(Target &target) const void MingwDllTool::do_prepare() { - string command = "dlltool"; - if(architecture->is_cross()) - command = format("%s-%s", architecture->get_cross_prefix(), command); - executable = builder.get_vfs().find_binary(command); + set_executable("dlltool", true); } Task *MingwDllTool::run(const Target &target) const diff --git a/source/tool.cpp b/source/tool.cpp index a23de63..65a4504 100644 --- a/source/tool.cpp +++ b/source/tool.cpp @@ -1,7 +1,11 @@ #include +#include +#include "architecture.h" +#include "builder.h" #include "tool.h" using namespace std; +using namespace Msp; Tool::Tool(Builder &b, const string &t): builder(b), @@ -45,6 +49,16 @@ void Tool::prepare() do_prepare(); } +void Tool::set_executable(const string &command, bool cross) +{ + if(cross && architecture->is_cross()) + return set_executable(format("%s-%s", architecture->get_cross_prefix(), command), false); + + executable = builder.get_vfs().find_binary(command); + if(!executable) + builder.problem(string(), format("Can't find executable %s for tool %s", command, tag)); +} + SubTool::SubTool(Tool &p): Tool(p), diff --git a/source/tool.h b/source/tool.h index 73be90d..93e2196 100644 --- a/source/tool.h +++ b/source/tool.h @@ -85,6 +85,11 @@ public: protected: virtual void do_prepare() { } + /** Locates an executable for the tool from the VFS. If it isn't found, a + problem is reported. If cross is true and the architecture is not native, + a cross prefix is added to the command. */ + void set_executable(const std::string &command, bool cross = false); + public: /** Invokes the tool to build a target. This should not be called directly; use Target::build() instead. */ -- 2.43.0 From 0d95fee118a3fcd78f153dca5721d9fe19b6f6bf Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 8 May 2013 12:36:22 +0300 Subject: [PATCH 08/16] Store problems at their source rather than globally This allows finer granularity in determining whether problems are preventing a build. In some cases it may be desirable to build just one component of a package, even if others have problems. --- source/binary.cpp | 5 ++-- source/binarypackage.cpp | 3 ++- source/builder.cpp | 52 +++++++++++++++++++++++++++++++++++++-- source/builder.h | 8 +----- source/buildercli.cpp | 8 +++--- source/component.cpp | 2 ++ source/component.h | 2 ++ source/package.cpp | 2 ++ source/package.h | 3 +++ source/packagemanager.cpp | 1 - source/problem.h | 15 ----------- source/target.cpp | 21 ++++++++++++++-- source/target.h | 8 +++++- source/tool.cpp | 2 +- source/tool.h | 3 +++ 15 files changed, 99 insertions(+), 36 deletions(-) delete mode 100644 source/problem.h diff --git a/source/binary.cpp b/source/binary.cpp index 9f0bfcd..e7b5e81 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -33,6 +33,7 @@ void Binary::find_dependencies() list queue; list dep_libs; + set missing_libs; queue.push_back(component); while(!queue.empty()) { @@ -56,8 +57,8 @@ void Binary::find_dependencies() else dep_libs.push_back(lib); } - else - builder.problem(package->get_name(), format("Couldn't find library %s for %s", *i, name)); + else if(missing_libs.insert(*i).second) + problems.push_back(format("Required library %s not found", *i)); } } diff --git a/source/binarypackage.cpp b/source/binarypackage.cpp index 22a4154..4c53821 100644 --- a/source/binarypackage.cpp +++ b/source/binarypackage.cpp @@ -72,7 +72,8 @@ void BinaryPackage::do_prepare() if(base_path.empty()) { - builder.problem(name, "Cannot locate files"); + // TODO report which files were not found + problems.push_back("Cannot locate files"); return; } diff --git a/source/builder.cpp b/source/builder.cpp index bbb95b6..81f4d8e 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -98,9 +98,57 @@ void Builder::set_logger(const Logger *l) logger = (l ? l : &default_logger); } -void Builder::problem(const string &p, const string &d) +list Builder::collect_problems() const { - problems.push_back(Problem(p, d)); + list problems; + set broken_packages; + set broken_components; + set broken_tools; + + const BuildGraph::TargetMap &targets = build_graph.get_targets(); + for(BuildGraph::TargetMap::const_iterator i=targets.begin(); i!=targets.end(); ++i) + if(i->second->is_broken()) + { + const list &tgt_problems = i->second->get_problems(); + for(list::const_iterator j=tgt_problems.begin(); j!=tgt_problems.end(); ++j) + problems.push_back(format("%s: %s", i->second->get_name(), *j)); + + const Package *package = i->second->get_package(); + if(package && !package->get_problems().empty()) + broken_packages.insert(package); + + const Component *component = i->second->get_component(); + if(component && !component->get_problems().empty()) + broken_components.insert(component); + + const Tool *tool = i->second->get_tool(); + if(tool && !tool->get_problems().empty()) + broken_tools.insert(tool); + } + + // TODO Sort components after their packages, and targets last + for(set::const_iterator i=broken_packages.begin(); i!=broken_packages.end(); ++i) + { + const list &pkg_problems = (*i)->get_problems(); + for(list::const_iterator j=pkg_problems.begin(); j!=pkg_problems.end(); ++j) + problems.push_back(format("%s: %s", (*i)->get_name(), *j)); + } + + for(set::const_iterator i=broken_components.begin(); i!=broken_components.end(); ++i) + { + const list &comp_problems = (*i)->get_problems(); + for(list::const_iterator j=comp_problems.begin(); j!=comp_problems.end(); ++j) + problems.push_back(format("%s/%s: %s", (*i)->get_package().get_name(), (*i)->get_name(), *j)); + } + + for(set::const_iterator i=broken_tools.begin(); i!=broken_tools.end(); ++i) + { + const list &tool_problems = (*i)->get_problems(); + for(list::const_iterator j=tool_problems.begin(); j!=tool_problems.end(); ++j) + problems.push_back(format("%s: %s", (*i)->get_tag(), *j)); + } + + return problems; } void Builder::load_build_file(const FS::Path &fn, const Config::InputOptions *opts, bool all) diff --git a/source/builder.h b/source/builder.h index 4c78a3d..3004ed2 100644 --- a/source/builder.h +++ b/source/builder.h @@ -12,7 +12,6 @@ #include "config.h" #include "logger.h" #include "packagemanager.h" -#include "problem.h" #include "target.h" #include "toolchain.h" #include "virtualfilesystem.h" @@ -46,9 +45,6 @@ private: void package(const std::string &); }; -public: - typedef std::list ProblemList; - private: typedef std::map BuildTypeMap; @@ -64,7 +60,6 @@ private: Logger default_logger; const Logger *logger; - ProblemList problems; Msp::FS::Path prefix; Msp::FS::Path tempdir; @@ -93,8 +88,7 @@ public: void set_logger(const Logger *); const Logger &get_logger() const { return *logger; } - void problem(const std::string &, const std::string &); - const ProblemList &get_problems() const { return problems; } + std::list collect_problems() const; /** Loads a build file. If opts is not null, it is used to configure any packages loaded from this file. If all is true, external packages are also diff --git a/source/buildercli.cpp b/source/buildercli.cpp index 6292318..a7dd1e2 100644 --- a/source/buildercli.cpp +++ b/source/buildercli.cpp @@ -255,12 +255,12 @@ int BuilderCLI::main() if(analyzer) analyzer->analyze(); - const Builder::ProblemList &problems = builder.get_problems(); - if(!problems.empty()) + if(build_graph.get_goals().is_broken()) { + list problems = builder.collect_problems(); IO::print(IO::cerr, "The following problems were detected:\n"); - for(Builder::ProblemList::const_iterator i=problems.begin(); i!=problems.end(); ++i) - IO::print(IO::cerr, " %s: %s\n", i->package, i->descr); + for(list::const_iterator i=problems.begin(); i!=problems.end(); ++i) + IO::print(IO::cerr, " %s\n", *i); if(!analyzer) IO::print(IO::cerr, "Please fix them and try again.\n"); return 1; diff --git a/source/component.cpp b/source/component.cpp index d0cc1e9..5e918c8 100644 --- a/source/component.cpp +++ b/source/component.cpp @@ -348,6 +348,8 @@ void Component::Loader::require(const string &n) Package *req = obj.package.get_builder().get_package_manager().find_package(n); if(req) obj.requires.push_back(req); + else + obj.problems.push_back(format("Required package %s not found", n)); } void Component::Loader::source(const string &s) diff --git a/source/component.h b/source/component.h index 3a743d0..7cbd1e1 100644 --- a/source/component.h +++ b/source/component.h @@ -60,6 +60,7 @@ protected: UseList uses; bool deflt; InstallMap install_map; + std::list problems; public: Component(SourcePackage &, Type, const std::string &); @@ -84,6 +85,7 @@ public: const Package::Requirements &get_required_packages() const { return requires; } const UseList &get_used_components() const { return uses; } bool is_default() const { return deflt; } + const std::list &get_problems() const { return problems; } /** Prepares any required packages. */ void prepare(); diff --git a/source/package.cpp b/source/package.cpp index 05bebcc..aa9160e 100644 --- a/source/package.cpp +++ b/source/package.cpp @@ -49,4 +49,6 @@ void Package::Loader::require(const string &n) Package *req = obj.builder.get_package_manager().find_package(n); if(req) obj.requires.push_back(req); + else + obj.problems.push_back(format("Required package %s not found", n)); } diff --git a/source/package.h b/source/package.h index aed1fd9..cd2d021 100644 --- a/source/package.h +++ b/source/package.h @@ -37,6 +37,7 @@ protected: Requirements requires; BuildInfo export_binfo; bool prepared; + std::list problems; bool use_pkgconfig; @@ -63,6 +64,8 @@ protected: public: bool is_prepared() const { return prepared; } + const std::list &get_problems() const { return problems; } + virtual void save_caches() { } }; diff --git a/source/packagemanager.cpp b/source/packagemanager.cpp index 0e2d8a0..ee07987 100644 --- a/source/packagemanager.cpp +++ b/source/packagemanager.cpp @@ -116,7 +116,6 @@ Package *PackageManager::find_package(const string &name) } catch(...) { - builder.problem(name, "not found"); not_found.insert(name); return 0; } diff --git a/source/problem.h b/source/problem.h deleted file mode 100644 index d3d10d4..0000000 --- a/source/problem.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef PROBLEM_H_ -#define PROBLEM_H_ - -#include -#include - -struct Problem -{ - std::string package; - std::string descr; - - Problem(const std::string &p, const std::string &d): package(p), descr(d) { } -}; - -#endif diff --git a/source/target.cpp b/source/target.cpp index 87b0d00..7f031ec 100644 --- a/source/target.cpp +++ b/source/target.cpp @@ -97,23 +97,40 @@ void Target::prepare() return; if(state==PREPARING) { - builder.problem((package ? package->get_name() : string()), "Dependency cycle detected at "+name); + problems.push_back("Dependency cycle detected"); + state = BROKEN; return; } state = PREPARING; if(tool) tool->prepare(); + find_dependencies(); + bool broken = !problems.empty(); + if(tool) + { if(FileTarget *tool_exe = tool->get_executable()) add_dependency(*tool_exe); + broken |= !tool->get_problems().empty(); + + // Only check package and component problems for buildable targets + // XXX How to propagate nested package problems? + broken |= (package && !package->get_problems().empty()); + broken |= (component && !component->get_problems().empty()); + } for(Dependencies::iterator i=depends.begin(); i!=depends.end(); ++i) + { (*i)->prepare(); + broken |= (*i)->is_broken(); + } check_rebuild(); - if(state==PREPARING) + if(broken) + state = BROKEN; + else if(state==PREPARING) state = UPTODATE; for(Dependencies::iterator i=depends.begin(); i!=depends.end(); ++i) diff --git a/source/target.h b/source/target.h index eda77d0..7c1d9a7 100644 --- a/source/target.h +++ b/source/target.h @@ -30,7 +30,8 @@ protected: PREPARING, REBUILD, BUILDING, - UPTODATE + UPTODATE, + BROKEN }; public: @@ -45,6 +46,7 @@ protected: Tool *tool; State state; std::string rebuild_reason; + std::list problems; Dependencies depends; Dependencies side_effects; @@ -123,6 +125,10 @@ protected: virtual void check_rebuild() = 0; public: + bool is_broken() const { return state==BROKEN; } + + const std::list &get_problems() const { return problems; } + /** Prepares the target by finding dependencies, recursively preparing them and then checking whether rebuilding is needed. */ void prepare(); diff --git a/source/tool.cpp b/source/tool.cpp index 65a4504..8aa75dc 100644 --- a/source/tool.cpp +++ b/source/tool.cpp @@ -56,7 +56,7 @@ void Tool::set_executable(const string &command, bool cross) executable = builder.get_vfs().find_binary(command); if(!executable) - builder.problem(string(), format("Can't find executable %s for tool %s", command, tag)); + problems.push_back(format("Can't find executable %s", command)); } diff --git a/source/tool.h b/source/tool.h index 93e2196..042199e 100644 --- a/source/tool.h +++ b/source/tool.h @@ -32,6 +32,7 @@ protected: SuffixList aux_suffixes; SearchPath system_path; bool prepared; + std::list problems; Tool(Builder &, const std::string &); Tool(Builder &, const Architecture &, const std::string &); @@ -91,6 +92,8 @@ protected: void set_executable(const std::string &command, bool cross = false); public: + const std::list &get_problems() const { return problems; } + /** Invokes the tool to build a target. This should not be called directly; use Target::build() instead. */ virtual Task *run(const Target &) const = 0; -- 2.43.0 From 36508cbdaa8cd45cdd5fc67eee763ad44e31a164 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 8 May 2013 15:20:56 +0300 Subject: [PATCH 09/16] Avoid a double verb in function name --- source/package.h | 2 +- source/pkgconfiggenerator.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/package.h b/source/package.h index cd2d021..eb61f06 100644 --- a/source/package.h +++ b/source/package.h @@ -52,7 +52,7 @@ public: const BuildInfo &get_exported_build_info() const { return export_binfo; } /// Indicates whether or not this package supports pkg-config - bool get_use_pkgconfig() const { return use_pkgconfig; } + bool uses_pkgconfig() const { return use_pkgconfig; } /** Prepares the package for building. Recursively prepares all required packages, populates build info and creates targets. */ diff --git a/source/pkgconfiggenerator.cpp b/source/pkgconfiggenerator.cpp index 677ef9b..b60eec4 100644 --- a/source/pkgconfiggenerator.cpp +++ b/source/pkgconfiggenerator.cpp @@ -46,7 +46,7 @@ void PkgConfigGenerator::Worker::main() IO::print(out, "Requires:"); const Package::Requirements &reqs = spkg.get_required_packages(); for(Package::Requirements::const_iterator i=reqs.begin(); i!=reqs.end(); ++i) - if((*i)->get_use_pkgconfig()) + if((*i)->uses_pkgconfig()) IO::print(out, " %s", (*i)->get_name()); out.put('\n'); -- 2.43.0 From c194bac9d508999c046a1f56c80b9419f77a8590 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 9 May 2013 10:12:52 +0300 Subject: [PATCH 10/16] Improvements for handling side effects Propagate rebuild from side effects to the primary target. This can happen if the side effect does not exist for whatever reason. As an additional safeguard, redirect any build attempts on side effects to the primary target. --- source/filetarget.cpp | 10 ++++------ source/target.cpp | 6 ++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/source/filetarget.cpp b/source/filetarget.cpp index b42580a..6ce5cfd 100644 --- a/source/filetarget.cpp +++ b/source/filetarget.cpp @@ -70,7 +70,7 @@ void FileTarget::touch() void FileTarget::check_rebuild() { - if(!tool) + if(!tool || needs_rebuild()) return; if(!mtime) @@ -89,12 +89,10 @@ void FileTarget::check_rebuild() if(!needs_rebuild()) { + // Some side effects might not exist for(Dependencies::iterator i=side_effects.begin(); (i!=side_effects.end() && !needs_rebuild()); ++i) - { - FileTarget *ft = dynamic_cast(*i); - if(ft && !ft->get_mtime()) - mark_rebuild((*i)->get_name()+" does not exist"); - } + if((*i)->needs_rebuild()) + mark_rebuild((*i)->get_name()+" needs rebuilding"); } if(!needs_rebuild() && package) diff --git a/source/target.cpp b/source/target.cpp index 7f031ec..f5b93a0 100644 --- a/source/target.cpp +++ b/source/target.cpp @@ -39,6 +39,9 @@ void Target::add_side_effect(Target &se) if(tool) se.set_tool(*tool); se.primary_target = this; + /* Side effects are checked for rebuild after the primary target. Recheck + the primary if a side effect is marked for rebuild. */ + se.signal_bubble_rebuild.connect(sigc::mem_fun(this, &Target::check_rebuild)); } Target *Target::get_buildable_target() @@ -139,6 +142,9 @@ void Target::prepare() Task *Target::build() { + if(primary_target) + return primary_target->build(); + Task *task = tool->run(*this); task->signal_finished.connect(sigc::mem_fun(this, &Target::build_finished)); state = BUILDING; -- 2.43.0 From 24981eb7ef702aa97b2ab90399ccd3fc23ce9ccf Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 9 May 2013 10:24:17 +0300 Subject: [PATCH 11/16] Remove all files in a side effect group when starting a task --- source/filetarget.cpp | 8 +++----- source/filetarget.h | 4 +--- source/target.cpp | 4 ++++ source/target.h | 4 ++++ source/task.cpp | 13 +++++++------ source/task.h | 9 ++++----- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/source/filetarget.cpp b/source/filetarget.cpp index 6ce5cfd..862ddbe 100644 --- a/source/filetarget.cpp +++ b/source/filetarget.cpp @@ -121,12 +121,10 @@ string FileTarget::create_build_signature() const return tool->create_build_signature(binfo); } -Task *FileTarget::build() +void FileTarget::build(Task &task) { - Task *task = Target::build(); - task->set_file(path); - task->set_unlink(true); - return task; + task.add_file(path); + task.set_unlink(true); } void FileTarget::build_finished(bool success) diff --git a/source/filetarget.h b/source/filetarget.h index da6b9a8..64567fd 100644 --- a/source/filetarget.h +++ b/source/filetarget.h @@ -41,10 +41,8 @@ protected: virtual std::string create_build_signature() const; -public: - virtual Task *build(); + virtual void build(Task &); -protected: virtual void build_finished(bool); public: diff --git a/source/target.cpp b/source/target.cpp index f5b93a0..dd75e9a 100644 --- a/source/target.cpp +++ b/source/target.cpp @@ -149,6 +149,10 @@ Task *Target::build() task->signal_finished.connect(sigc::mem_fun(this, &Target::build_finished)); state = BUILDING; + build(*task); + for(Dependencies::const_iterator i=side_effects.begin(); i!=side_effects.end(); ++i) + (*i)->build(*task); + return task; } diff --git a/source/target.h b/source/target.h index 7c1d9a7..6b9cc90 100644 --- a/source/target.h +++ b/source/target.h @@ -138,6 +138,10 @@ public: virtual Task *build(); protected: + /** Targets can override this to do additional setup on the Task. This is + also called on side effects, which normally do not get built by themselves. */ + virtual void build(Task &) { } + /** Handler for Task::signal_finished. */ virtual void build_finished(bool); diff --git a/source/task.cpp b/source/task.cpp index f6fa7b2..75b725e 100644 --- a/source/task.cpp +++ b/source/task.cpp @@ -3,15 +3,16 @@ #include #include "task.h" +using namespace std; using namespace Msp; Task::Task(): unlink(false) { } -void Task::set_file(const FS::Path &f) +void Task::add_file(const FS::Path &f) { - file = f; + files.push_back(f); } void Task::set_unlink(bool u) @@ -21,16 +22,16 @@ void Task::set_unlink(bool u) void Task::prepare() { - if(!file.empty()) + for(list::const_iterator i=files.begin(); i!=files.end(); ++i) { - if(FS::exists(file)) + if(FS::exists(*i)) { // If the file exists, the directory it's in must exist too - FS::unlink(file); + FS::unlink(*i); } else { - FS::Path dir = FS::dirname(file); + FS::Path dir = FS::dirname(*i); if(!FS::exists(dir)) FS::mkpath(dir, 0755); } diff --git a/source/task.h b/source/task.h index 0732453..183deee 100644 --- a/source/task.h +++ b/source/task.h @@ -22,7 +22,7 @@ public: sigc::signal signal_finished; - Msp::FS::Path file; + std::list files; bool unlink; protected: @@ -31,9 +31,9 @@ public: virtual ~Task() { } /** Associate the task with a file. */ - void set_file(const Msp::FS::Path &); + void add_file(const Msp::FS::Path &); - /** If set to true, the associated file is removed before the task is + /** If set to true, the associated files are removed before the task is started. */ void set_unlink(bool = true); @@ -45,8 +45,7 @@ public: virtual void start() = 0; protected: - /** Ensures that the output directory exists and removes the file if - necessary. */ + /// Ensures that the output directory exists and removes files if necessary. void prepare(); public: -- 2.43.0 From 43d1143e6dc6bbf3797dbaae42d4bfce3dea5d88 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 9 May 2013 11:19:37 +0300 Subject: [PATCH 12/16] Include architecture in Binary build signature This reduces problems if the same source directory is shared between computers of different architectures, or if building versions for different CPUs. --- source/binary.cpp | 4 +++- source/tool.h | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source/binary.cpp b/source/binary.cpp index e7b5e81..a3f3c9b 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -81,10 +81,12 @@ string Binary::create_build_signature() const object_tools.insert((*i)->get_tool()); list sigs; - sigs.push_back(tool->create_build_signature(component->get_build_info())); for(set::const_iterator i=object_tools.begin(); i!=object_tools.end(); ++i) sigs.push_back((*i)->create_build_signature(component->get_build_info())); sigs.sort(); + sigs.push_front(tool->create_build_signature(component->get_build_info())); + if(const Architecture *arch = tool->get_architecture()) + sigs.push_front(arch->get_name()); return join(sigs.begin(), sigs.end(), ";"); } diff --git a/source/tool.h b/source/tool.h index 042199e..be3646c 100644 --- a/source/tool.h +++ b/source/tool.h @@ -41,6 +41,10 @@ public: const std::string &get_tag() const { return tag; } + /** Returns the architecture this tool build for. May return null if the + tool is architecture-agnostic. */ + const Architecture *get_architecture() const { return architecture; } + /** Returns a target for the tool's own executable. If the tool does not use an external program, returns null. */ FileTarget *get_executable() const { return executable; } -- 2.43.0 From 1496723307ed47b60d3116623ba383e85b50efef Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 24 May 2013 15:44:37 +0300 Subject: [PATCH 13/16] Remove deprecated features All of these have been deprecated for nearly a year, and I don't have any active projects using them. --- source/builder.cpp | 6 ---- source/builder.h | 1 - source/condition.cpp | 76 ---------------------------------------- source/condition.h | 39 --------------------- source/sourcepackage.cpp | 57 ++---------------------------- source/sourcepackage.h | 5 --- 6 files changed, 2 insertions(+), 182 deletions(-) delete mode 100644 source/condition.cpp delete mode 100644 source/condition.h diff --git a/source/builder.cpp b/source/builder.cpp index 81f4d8e..b73618f 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -300,7 +300,6 @@ Builder::Loader::Loader(Builder &b, const Config::InputOptions *o, bool a): add("architecture", &Loader::architecture); add("binary_package", &Loader::binpkg); add("build_type", &Loader::build_type); - add("profile", &Loader::profile); add("package", &Loader::package); if(!obj.top_loader) @@ -336,11 +335,6 @@ void Builder::Loader::build_type(const string &n) obj.build_type = &i->second; } -void Builder::Loader::profile(const string &) -{ - IO::print("Profiles are deprecated\n"); -} - void Builder::Loader::package(const string &n) { SourcePackage *pkg = new SourcePackage(obj, n, get_source()); diff --git a/source/builder.h b/source/builder.h index 3004ed2..7998a39 100644 --- a/source/builder.h +++ b/source/builder.h @@ -41,7 +41,6 @@ private: void architecture(const std::string &); void binpkg(const std::string &); void build_type(const std::string &); - void profile(const std::string &); void package(const std::string &); }; diff --git a/source/condition.cpp b/source/condition.cpp deleted file mode 100644 index 413870e..0000000 --- a/source/condition.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include "builder.h" -#include "condition.h" -#include "sourcepackage.h" - -using namespace std; -using namespace Msp; - -Condition::Condition(SourcePackage &p, const string &expr): - pkg(p) -{ - vector parts = split(expr); - - for(vector::iterator i=parts.begin(); i!=parts.end(); ++i) - { - if(*i=="and") - continue; - - string::size_type token = i->find_first_of("=!"); - if(token==string::npos) - expression.insert(Expression::value_type(*i, "=")); - else if(token==0 && (*i)[0]=='!') - expression.insert(Expression::value_type(i->substr(1), "!")); - else - expression.insert(Expression::value_type(i->substr(0, token), i->substr(token))); - } -} - -bool Condition::eval() -{ - const Config &conf = pkg.get_config(); - - bool result = true; - for(Expression::iterator i=expression.begin(); i!=expression.end(); ++i) - { - bool neg = (i->second[0]=='!'); - unsigned start = 1; - if(i->second[1]=='=') - ++start; - string value = i->second.substr(start); - - bool match = false; - if(conf.is_option(i->first)) - { - if(value.empty()) - match = lexical_cast(conf.get_option(i->first).value); - else - match = (conf.get_option(i->first).value==value); - } - else if(i->first=="arch") - match = pkg.get_builder().get_current_arch().match_name(value); - - if(match==neg) - result = false; - } - - return result; -} - - -Condition::Loader::Loader(Condition &c): - DataFile::ObjectLoader(c) -{ - add("require", &Loader::require); - add("build_info", &Loader::build_info); -} - -void Condition::Loader::require(const string &pkg) -{ - obj.requires.push_back(pkg); -} - -void Condition::Loader::build_info() -{ - load_sub(obj.build_info); -} diff --git a/source/condition.h b/source/condition.h deleted file mode 100644 index 0cdc2bb..0000000 --- a/source/condition.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef CONDITION_H_ -#define CONDITION_H_ - -#include -#include "buildinfo.h" - -class Config; -class SourcePackage; - -class Condition -{ -public: - class Loader: public Msp::DataFile::ObjectLoader - { - public: - Loader(Condition &); - private: - void require(const std::string &); - void build_info(); - }; - - typedef std::list RequireList; - -private: - typedef std::map Expression; - - SourcePackage &pkg; - Expression expression; - RequireList requires; - BuildInfo build_info; - -public: - Condition(SourcePackage &, const std::string &); - const RequireList &get_requires() const { return requires; } - const BuildInfo &get_build_info() const { return build_info; } - bool eval(); -}; - -#endif diff --git a/source/sourcepackage.cpp b/source/sourcepackage.cpp index faf3bfe..e3f1109 100644 --- a/source/sourcepackage.cpp +++ b/source/sourcepackage.cpp @@ -166,40 +166,21 @@ void SourcePackage::Loader::init(const Config::InputOptions *o) add("description", &SourcePackage::description); add("build_info", &Loader::build_info); add("feature", &Loader::feature); - add("if", &Loader::condition); add("if_feature", &Loader::if_feature); add("program", &Loader::component); add("library", &Loader::component); add("module", &Loader::component); - add("headers", &Loader::headers); add("install", &Loader::component); add("interface_version", &Loader::interface_version); add("datapack", &Loader::component); add("source_tarball", &Loader::source_tarball); add("tarball", &Loader::tarball); - add("tar_file", &Loader::tar_file); add("version", &Loader::version); } void SourcePackage::Loader::finish() { obj.components.sort(component_sort); - - for(map::const_iterator i=install_map.begin(); i!=install_map.end(); ++i) - { - for(ComponentList::iterator j=obj.components.begin(); j!=obj.components.end(); ++j) - { - const Component::SourceList &sources = j->get_sources(); - for(Component::SourceList::const_iterator k=sources.begin(); k!=sources.end(); ++k) - { - string k_str = k->str(); - if(!i->first.compare(0, k_str.size(), k_str)) - { - const_cast(j->get_install_map()).add_mapping(obj.source_dir/i->first, i->second); - } - } - } - } } void SourcePackage::Loader::feature(const string &n, const string &d) @@ -219,14 +200,6 @@ void SourcePackage::Loader::feature(const string &n, const string &d) } } -void SourcePackage::Loader::condition(const string &c) -{ - IO::print("%s: Note: Old-style conditions are deprecated\n", get_source()); - Condition cond(obj, c); - if(cond.eval()) - load_sub_with(*this); -} - template void SourcePackage::Loader::component(const string &n) { @@ -240,16 +213,6 @@ void SourcePackage::Loader::build_info() load_sub(obj.build_info); } -void SourcePackage::Loader::headers(const string &n) -{ - IO::print("%s: Note: headers components are deprecated\n", get_source()); - Component comp(obj, Component::LIBRARY, n); - load_sub(comp); - const Component::SourceList &sources = comp.get_sources(); - for(Component::SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) - install_map[i->str()] = "include/"+comp.get_name(); -} - void SourcePackage::Loader::if_feature(const string &cond) { bool match = obj.match_feature(cond); @@ -272,24 +235,8 @@ void SourcePackage::Loader::source_tarball() void SourcePackage::Loader::tarball(const string &n) { - if(n=="@src") - { - IO::print("%s: Note: Use source_tarball instead of tarball \"@src\"\n", get_source()); - load_sub(*obj.source_tarball); - } - else - { - Component trbl(obj, Component::TARBALL, n); - load_sub(trbl); - } -} - -void SourcePackage::Loader::tar_file(const string &f) -{ - IO::print("%s: Note: tar_file is deprecated\n", get_source()); - for(ComponentList::iterator i=obj.components.begin(); i!=obj.components.end(); ++i) - if(i->get_type()==Component::TARBALL && i->get_name()=="@src") - const_cast(i->get_sources()).push_back((obj.source_dir/f).str()); + Component trbl(obj, Component::TARBALL, n); + load_sub(trbl); } void SourcePackage::Loader::version(const string &v) diff --git a/source/sourcepackage.h b/source/sourcepackage.h index e5c3152..1e0e5f9 100644 --- a/source/sourcepackage.h +++ b/source/sourcepackage.h @@ -6,7 +6,6 @@ #include "buildinfo.h" #include "cache.h" #include "component.h" -#include "condition.h" #include "config.h" #include "feature.h" #include "package.h" @@ -32,7 +31,6 @@ public: { private: const Config::InputOptions *options; - std::map install_map; public: Loader(SourcePackage &); @@ -43,14 +41,11 @@ public: void feature(const std::string &, const std::string &); template void component(const std::string &); - void condition(const std::string &); void build_info(); - void headers(const std::string &); void if_feature(const std::string &); void interface_version(const std::string &); void source_tarball(); void tarball(const std::string &); - void tar_file(const std::string &); void version(const std::string &); }; -- 2.43.0 From 8a2579d4b8e510405402ec316d53a509152aa6ea Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 24 May 2013 18:37:48 +0300 Subject: [PATCH 14/16] Make toolchains hierarchial This enables eventual tool plugins to give out all of their tools in one bundle. --- source/toolchain.cpp | 28 ++++++++++++++++++++++++++++ source/toolchain.h | 5 +++++ 2 files changed, 33 insertions(+) diff --git a/source/toolchain.cpp b/source/toolchain.cpp index 9d23403..953fe11 100644 --- a/source/toolchain.cpp +++ b/source/toolchain.cpp @@ -9,6 +9,8 @@ Toolchain::~Toolchain() { for(ToolMap::iterator i=tools.begin(); i!=tools.end(); ++i) delete i->second; + for(ToolchainList::iterator i=chains.begin(); i!=chains.end(); ++i) + delete *i; } void Toolchain::add_tool(Tool *tool) @@ -16,8 +18,30 @@ void Toolchain::add_tool(Tool *tool) insert_unique(tools, tool->get_tag(), tool); } +void Toolchain::add_toolchain(Toolchain *chain) +{ + chains.push_back(chain); +} + +bool Toolchain::has_tool(const string &tag) const +{ + if(tools.count(tag)) + return true; + for(ToolchainList::const_iterator i=chains.begin(); i!=chains.end(); ++i) + if((*i)->has_tool(tag)) + return true; + return false; +} + Tool &Toolchain::get_tool(const string &tag) const { + if(!tools.count(tag)) + { + for(ToolchainList::const_iterator i=chains.begin(); i!=chains.end(); ++i) + if((*i)->has_tool(tag)) + return (*i)->get_tool(tag); + } + return *get_item(tools, tag); } @@ -27,5 +51,9 @@ Tool *Toolchain::get_tool_for_suffix(const string &suffix, bool aux) const if(i->second->accepts_suffix(suffix, aux)) return i->second; + for(ToolchainList::const_iterator i=chains.begin(); i!=chains.end(); ++i) + if(Tool *tool = (*i)->get_tool_for_suffix(suffix, aux)) + return tool; + return 0; } diff --git a/source/toolchain.h b/source/toolchain.h index 572e42f..8449680 100644 --- a/source/toolchain.h +++ b/source/toolchain.h @@ -1,6 +1,7 @@ #ifndef TOOLCHAIN_H_ #define TOOLCHAIN_H_ +#include #include #include @@ -13,13 +14,17 @@ class Toolchain { private: typedef std::map ToolMap; + typedef std::list ToolchainList; ToolMap tools; + ToolchainList chains; public: ~Toolchain(); void add_tool(Tool *); + void add_toolchain(Toolchain *); + bool has_tool(const std::string &) const; Tool &get_tool(const std::string &) const; Tool *get_tool_for_suffix(const std::string &, bool = false) const; }; -- 2.43.0 From 88e3ad4afa2010507227c0c0ffb9d1ce08f61e2a Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 24 May 2013 18:38:57 +0300 Subject: [PATCH 15/16] Group most existing tools in sub-toolchains --- source/builder.cpp | 21 ++++----------------- source/builtintools.cpp | 11 +++++++++++ source/builtintools.h | 14 ++++++++++++++ source/gnutools.cpp | 17 +++++++++++++++++ source/gnutools.h | 15 +++++++++++++++ 5 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 source/builtintools.cpp create mode 100644 source/builtintools.h create mode 100644 source/gnutools.cpp create mode 100644 source/gnutools.h diff --git a/source/builder.cpp b/source/builder.cpp index b73618f..cf49f41 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -11,19 +11,13 @@ #include #include "binarypackage.h" #include "builder.h" -#include "copy.h" +#include "builtintools.h" #include "datatool.h" -#include "gnuarchiver.h" -#include "gnuccompiler.h" -#include "gnucxxcompiler.h" -#include "gnulinker.h" +#include "gnutools.h" #include "installedfile.h" -#include "mingwdlltool.h" #include "package.h" -#include "pkgconfiggenerator.h" #include "sharedlibrary.h" #include "sourcepackage.h" -#include "tar.h" #include "task.h" #include "virtualtarget.h" @@ -81,15 +75,8 @@ void Builder::set_temp_directory(const FS::Path &p) void Builder::add_default_tools() { - toolchain.add_tool(new GnuCCompiler(*this, *current_arch)); - toolchain.add_tool(new GnuCxxCompiler(*this, *current_arch)); - toolchain.add_tool(new GnuLinker(*this, *current_arch)); - toolchain.add_tool(new GnuArchiver(*this, *current_arch)); - toolchain.add_tool(new Copy(*this)); - toolchain.add_tool(new Tar(*this)); - toolchain.add_tool(new PkgConfigGenerator(*this)); - if(current_arch->get_system()=="windows") - toolchain.add_tool(new MingwDllTool(*this, *current_arch)); + toolchain.add_toolchain(new GnuTools(*this, *current_arch)); + toolchain.add_toolchain(new BuiltinTools(*this)); toolchain.add_tool(new DataTool(*this)); } diff --git a/source/builtintools.cpp b/source/builtintools.cpp new file mode 100644 index 0000000..db1d4f3 --- /dev/null +++ b/source/builtintools.cpp @@ -0,0 +1,11 @@ +#include "builtintools.h" +#include "copy.h" +#include "pkgconfiggenerator.h" +#include "tar.h" + +BuiltinTools::BuiltinTools(Builder &builder) +{ + add_tool(new Copy(builder)); + add_tool(new Tar(builder)); + add_tool(new PkgConfigGenerator(builder)); +} diff --git a/source/builtintools.h b/source/builtintools.h new file mode 100644 index 0000000..e3b0256 --- /dev/null +++ b/source/builtintools.h @@ -0,0 +1,14 @@ +#ifndef BUILTINTOOLS_H_ +#define BUILTINTOOLS_H_ + +#include "toolchain.h" + +class Builder; + +class BuiltinTools: public Toolchain +{ +public: + BuiltinTools(Builder &); +}; + +#endif diff --git a/source/gnutools.cpp b/source/gnutools.cpp new file mode 100644 index 0000000..20463e6 --- /dev/null +++ b/source/gnutools.cpp @@ -0,0 +1,17 @@ +#include "architecture.h" +#include "gnuarchiver.h" +#include "gnuccompiler.h" +#include "gnucxxcompiler.h" +#include "gnulinker.h" +#include "gnutools.h" +#include "mingwdlltool.h" + +GnuTools::GnuTools(Builder &builder, const Architecture &arch) +{ + add_tool(new GnuCCompiler(builder, arch)); + add_tool(new GnuCxxCompiler(builder, arch)); + add_tool(new GnuLinker(builder, arch)); + add_tool(new GnuArchiver(builder, arch)); + if(arch.get_system()=="windows") + add_tool(new MingwDllTool(builder, arch)); +} diff --git a/source/gnutools.h b/source/gnutools.h new file mode 100644 index 0000000..98e2856 --- /dev/null +++ b/source/gnutools.h @@ -0,0 +1,15 @@ +#ifndef GNUTOOLS_H_ +#define GNUTOOLS_H_ + +#include "toolchain.h" + +class Architecture; +class Builder; + +class GnuTools: public Toolchain +{ +public: + GnuTools(Builder &, const Architecture &); +}; + +#endif -- 2.43.0 From 33202532d4afbebdef4047f6bd216eca22d27813 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 24 May 2013 20:09:21 +0300 Subject: [PATCH 16/16] The mingw port of gcc doesn't recognize -pthread --- source/gnucompiler.cpp | 2 +- source/gnulinker.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/gnucompiler.cpp b/source/gnucompiler.cpp index ec1959a..5f69c0d 100644 --- a/source/gnucompiler.cpp +++ b/source/gnucompiler.cpp @@ -121,7 +121,7 @@ Task *GnuCompiler::run(const Target &target) const else argv.push_back(format("-O%d", binfo.optimize)); } - if(binfo.threads) + if(binfo.threads && architecture->get_system()!="windows") argv.push_back("-pthread"); if((comp.get_type()==Component::LIBRARY || comp.get_type()==Component::MODULE) && architecture->get_system()!="windows") argv.push_back("-fPIC"); diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index 02708cc..9ae5d64 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -188,7 +188,7 @@ Task *GnuLinker::Linker::run(const Target &target) const argv.push_back("-L"+i->str()); if(binfo.strip) argv.push_back("-s"); - if(binfo.threads) + if(binfo.threads && architecture->get_system()!="windows") argv.push_back("-pthread"); const Architecture &native_arch = builder.get_native_arch(); -- 2.43.0