]> git.tdb.fi Git - builder.git/commitdiff
Add a way for components to use libraries from the same package
authorMikko Rasa <tdb@tdb.fi>
Fri, 27 Jul 2012 07:22:18 +0000 (10:22 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 27 Jul 2012 07:22:18 +0000 (10:22 +0300)
Readme.txt
source/component.cpp
source/component.h

index 3a26dcc93b40f16e68c2771f3cb5d1d964334434..521bd7fa61851ce032a9ba5e6f5d29b3eea346c0 100644 (file)
@@ -259,7 +259,7 @@ Inside the package can be some informational statements:
   version "0.1";
   description "My awesome library";
 
-Packages may also depend on other packages:
+Packages may also require other packages:
 
   require "otherlib";
 
@@ -301,6 +301,15 @@ The default is not to install any components.  The installation directory is
 automatically determined from the component type.  Library components will also
 install any headers which were used to build the library.
 
+Components can have requirements, just like packages.  They can also use
+library components from the same package:
+
+  use "mylib_common";
+
+Libraries used in this way will always be linked in statically.  This can be
+useful in organizing code when multiple components in a package share a common
+part.
+
 Packages may want to offer optional features, for example to allow the user to
 choose whether to use a particular external library:
 
index 4a889cb1750903209638a2cb2b8d8b3945847793..feb5094b27a071fa8823eabd4e09c2fae466a11d 100644 (file)
@@ -190,6 +190,24 @@ void Component::create_targets() const
                else
                        results.push_back(linker.create_target(objs));
 
+               const Target::Dependencies &world_deps = builder.get_target("world")->get_dependencies();
+               for(UseList::const_iterator i=uses.begin(); i!=uses.end(); ++i)
+               {
+                       /* The world target depends on all primary targets; look for the
+                       static library belonging to the component.  This is a bit roundabout
+                       way but gets the job done. */
+                       bool found = false;
+                       for(Target::Dependencies::const_iterator j=world_deps.begin(); j!=world_deps.end(); ++j)
+                               if((*j)->get_component()==*i && dynamic_cast<StaticLibrary *>(*j))
+                               {
+                                       results.front()->add_dependency(**j);
+                                       found = true;
+                                       break;
+                               }
+                       if(!found)
+                               builder.problem(package.get_name(), format("Can't find static library %s for component %s", (*i)->get_name(), name));
+               }
+
                for(list<Target *>::const_iterator i=results.begin(); i!=results.end(); ++i)
                {
                        builder.add_primary_target(**i);
@@ -237,6 +255,7 @@ Component::Loader::Loader(Component &c):
        add("build_info",      &Loader::build_info);
        add("require",         &Loader::require);
        add("default",         &Component::deflt);
+       add("use",             &Loader::use);
 }
 
 void Component::Loader::source(const string &s)
@@ -260,3 +279,15 @@ void Component::Loader::install_map()
 {
        load_sub(obj.install_map, obj.package.get_source_directory());
 }
+
+void Component::Loader::use(const string &n)
+{
+       const SourcePackage::ComponentList &components = obj.package.get_components();
+       for(SourcePackage::ComponentList::const_iterator i=components.begin(); i!=components.end(); ++i)
+               if(i->get_name()==n && i->get_type()==LIBRARY)
+               {
+                       obj.uses.push_back(&*i);
+                       return;
+               }
+       error(format("Unknown library component '%s'", n));
+}
index e68bc38f612acc2d0476792f271b831477671ed8..2e9e534c0ca0973d2638a8902446c926bdfe0b67 100644 (file)
@@ -28,6 +28,7 @@ public:
                void require(const std::string &);
                void build_info();
                void install_map();
+               void use(const std::string &);
        };
 
        enum Type
@@ -41,6 +42,7 @@ public:
        };
 
        typedef std::list<Msp::FS::Path> SourceList;
+       typedef std::list<const Component *> UseList;
 
 protected:
        SourcePackage &package;
@@ -50,6 +52,7 @@ protected:
        bool install;
        BuildInfo build_info;
        Package::Requirements requires;
+       UseList uses;
        bool deflt;
        InstallMap install_map;
 
@@ -72,6 +75,7 @@ public:
        bool get_install() const { return install; }
        const InstallMap &get_install_map() const { return install_map; }
        const Package::Requirements &get_required_packages() const { return requires; }
+       const UseList &get_used_components() const { return uses; }
        bool is_default() const { return deflt; }
 
        /** Prepares any required packages. */