From: Mikko Rasa Date: Wed, 7 Mar 2007 20:21:58 +0000 (+0000) Subject: Support building modular programs X-Git-Tag: 0.9~39 X-Git-Url: http://git.tdb.fi/?p=builder.git;a=commitdiff_plain;h=09325a99816a966bc17a0ec9a0a197efc6ce0349 Support building modular programs --- diff --git a/source/builder.cpp b/source/builder.cpp index 1afc741..f23e85a 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -1,12 +1,11 @@ #include #include #include -#include -#include #include #include #include #include +#include #include #include #include "action.h" diff --git a/source/component.cpp b/source/component.cpp index 22392f0..27a4c53 100644 --- a/source/component.cpp +++ b/source/component.cpp @@ -1,13 +1,18 @@ +#include #include "component.h" #include "package.h" using namespace std; +#include + Component::Component(Package &p, Type t, const string &n): pkg(p), type(t), name(n), - install(false) + install(false), + module_host(0), + modular(false) { } /** @@ -34,6 +39,18 @@ void Component::create_build_info() build_info.add(i->get_package()->get_exported_binfo()); } + if(modular) + { + build_info.ldflags.push_back("-rdynamic"); + build_info.libs.push_back("dl"); + } + else if(module_host) + { + const PathList &host_src=module_host->get_sources(); + for(PathList::const_iterator i=host_src.begin(); i!=host_src.end(); ++i) + build_info.incpath.push_back(i->str()); + } + build_info.unique(); } @@ -45,6 +62,8 @@ Component::Loader::Loader(Component &c): add("install_headers", &Component::install_headers); add("build_info", &Loader::build_info); add("require", &Loader::require); + add("modular", &Loader::modular); + add("host", &Loader::host); } void Component::Loader::source(const string &s) @@ -57,6 +76,28 @@ void Component::Loader::require(const string &n) comp.requires.push_back(PackageRef(comp.pkg.get_builder(), n)); } +void Component::Loader::modular() +{ + if(comp.type!=PROGRAM) + throw Msp::Exception("Only programs can be modular"); + comp.modular=true; +} + +void Component::Loader::host(const string &n) +{ + const ComponentList &comps=comp.pkg.get_components(); + for(ComponentList::const_iterator i=comps.begin(); i!=comps.end(); ++i) + if(i->get_name()==n) + { + if(i->get_type()!=PROGRAM || !i->get_modular()) + throw Msp::Exception("Module host must be a modular program"); + comp.module_host=&*i; + return; + } + + throw Msp::Exception("Unknown component"); +} + void Component::Loader::build_info() { load_sub(comp.build_info); diff --git a/source/component.h b/source/component.h index 82b32e4..e1df73a 100644 --- a/source/component.h +++ b/source/component.h @@ -30,6 +30,8 @@ public: void source(const std::string &); void require(const std::string &); + void modular(); + void host(const std::string &); void build_info(); }; @@ -49,6 +51,7 @@ public: const BuildInfo &get_build_info() const { return build_info; } bool get_install() const { return install; } const std::string &get_install_headers() const { return install_headers; } + bool get_modular() const { return modular; } const PkgRefList &get_requires() const { return requires; } void resolve_refs(); void create_build_info(); @@ -59,6 +62,8 @@ protected: PathList sources; bool install; std::string install_headers; + const Component *module_host; + bool modular; BuildInfo build_info; PkgRefList requires; }; diff --git a/source/executable.cpp b/source/executable.cpp index 1f23990..a5a944e 100644 --- a/source/executable.cpp +++ b/source/executable.cpp @@ -28,8 +28,8 @@ void Executable::find_depends() { LibMode libmode=package->get_library_mode(); - //XXX Duplicate libraries? list queue; + list dep_libs; queue.push_back(&comp); while(!queue.empty()) { @@ -44,7 +44,8 @@ void Executable::find_depends() { if(contains(depends, lib)) continue; - add_depend(lib); + + dep_libs.push_front(lib); if(dynamic_cast(lib)) lib=lib->get_depends().front(); @@ -57,6 +58,9 @@ void Executable::find_depends() } } + for(list::iterator i=dep_libs.begin(); i!=dep_libs.end(); ++i) + add_depend(*i); + deps_ready=true; } @@ -78,6 +82,8 @@ string Executable::generate_target_name(const Component &c) prefix="lib"; suffix=".so"; } + else if(c.get_type()==Component::MODULE) + suffix=".m"; return (c.get_package().get_out_dir()/(prefix+c.get_name()+suffix)).str(); } diff --git a/source/link.cpp b/source/link.cpp index 2ff5a97..4a96ff2 100644 --- a/source/link.cpp +++ b/source/link.cpp @@ -23,7 +23,7 @@ Link::Link(Builder &b, const Executable &exe): //XXX Determine whether to use g++ or gcc argv.push_back(prefix+"g++"); - if(comp.get_type()==Component::LIBRARY) + if(comp.get_type()==Component::LIBRARY || comp.get_type()==Component::MODULE) argv.push_back("-shared"); else if(comp.get_package().get_library_mode()==ALL_STATIC) argv.push_back("-static"); diff --git a/source/package.cpp b/source/package.cpp index 0bea2a9..031ceb5 100644 --- a/source/package.cpp +++ b/source/package.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include "builder.h" #include "misc.h" #include "package.h" @@ -270,7 +270,7 @@ void Package::create_build_info() export_binfo.libpath.push_back((Path::Path(config.get_option("prefix").value)/"lib").str()); string optimize=config.get_option("optimize").value; - if(strtol(optimize)) + if(lexical_cast(optimize)) { build_info.cflags.push_back("-O"+optimize); string cpu=config.get_option("cpu").value; @@ -278,7 +278,7 @@ void Package::create_build_info() build_info.cflags.push_back("-march="+cpu); } - if(strtobool(config.get_option("debug").value)) + if(lexical_cast(config.get_option("debug").value)) { build_info.cflags.push_back("-ggdb"); build_info.defines.push_back("DEBUG"); @@ -313,6 +313,7 @@ Package::Loader::Loader(Package &p): add("require", &Loader::require); add("program", &Loader::program); add("library", &Loader::library); + add("module", &Loader::module); add("headers", &Loader::headers); add("build_info", &Loader::build_info); } @@ -336,6 +337,13 @@ void Package::Loader::library(const string &n) pkg.components.push_back(prog); } +void Package::Loader::module(const string &n) +{ + Component prog(pkg, Component::MODULE, n); + load_sub(prog); + pkg.components.push_back(prog); +} + void Package::Loader::headers(const string &n) { Component prog(pkg, Component::HEADERS, n); diff --git a/source/package.h b/source/package.h index 96fb676..68e0c22 100644 --- a/source/package.h +++ b/source/package.h @@ -43,6 +43,7 @@ public: void require(const std::string &); void program(const std::string &); void library(const std::string &); + void module(const std::string &); void headers(const std::string &); void build_info(); };