From c51e8844f19c31b2809ba459a1659d3b94a86f89 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 24 Apr 2013 13:03:30 +0300 Subject: [PATCH] Add a feature for overlay source directories This allows separation of architecture- or feature-specific source files in their own directories. --- bootstrap.sh | 6 ++++- source/component.cpp | 59 ++++++++++++++++++++++++++++++++++++++++--- source/component.h | 7 +++++ source/installmap.cpp | 14 +++++++++- source/objectfile.cpp | 13 ++++++++++ 5 files changed, 93 insertions(+), 6 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 70d0323..5cb4012 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -61,7 +61,7 @@ for i in $REQUIRED; do else ln -sf $path/source "$INCLUDEDIR/msp/$i" fi - sources="$sources `find $path/source -name '*.cpp'`" + sources="$sources `find $path/source \( -name windows -prune \) -o \( -name '*.cpp' -print \)`" fi done @@ -72,6 +72,10 @@ if [ ! -z "$missing" ]; then exit 1 fi +for i in "$INCLUDEDIR/msp/"*/unix; do + CFLAGS="$CFLAGS -iquote $i -iquote ${i%/unix}" +done + echo "Compiling builder-stage1. This may take several minutes." g++ $sources -o builder-stage1 $CFLAGS $LIBS echo "Using builder-stage1 to compile builder." diff --git a/source/component.cpp b/source/component.cpp index 3b1f872..566cf88 100644 --- a/source/component.cpp +++ b/source/component.cpp @@ -101,6 +101,32 @@ void Component::create_build_info() } } +BuildInfo Component::get_build_info_for_path(const FS::Path &path) const +{ + // XXX Cache these and check that the directories actually exist before adding them + BuildInfo binfo = build_info; + if(!overlays.empty()) + { + FS::Path dir = FS::dirname(path); + string last = FS::basename(dir); + for(OverlayList::const_iterator i=overlays.begin(); i!=overlays.end(); ++i) + if(last==*i) + { + dir = FS::dirname(dir); + break; + } + + for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i) + if(dir==*i) + { + binfo.local_incpath.push_back(dir); + for(OverlayList::const_iterator j=overlays.begin(); j!=overlays.end(); ++j) + binfo.local_incpath.push_back(*i/ *j); + } + } + return binfo; +} + void Component::create_targets() const { Builder &builder = package.get_builder(); @@ -237,13 +263,32 @@ Component::SourceList Component::collect_source_files() const FS::Path path(*i); if(FS::is_dir(path)) { - package.get_builder().get_logger().log("files", format("Traversing %s", path)); - list sfiles = list_files(path); - for(list::iterator j=sfiles.begin(); j!=sfiles.end(); ++j) - files.push_back(path / *j); + SourceList dirs; + dirs.push_back(path); + for(OverlayList::const_iterator j=overlays.begin(); j!=overlays.end(); ++j) + { + FS::Path opath = path / *j; + if(FS::is_dir(opath)) + dirs.push_back(opath); + } + for(SourceList::const_iterator j=dirs.begin(); j!=dirs.end(); ++j) + { + package.get_builder().get_logger().log("files", format("Traversing %s", *j)); + list sfiles = list_files(*j); + for(list::iterator k=sfiles.begin(); k!=sfiles.end(); ++k) + files.push_back(*j / *k); + } } else + { files.push_back(path); + for(OverlayList::const_iterator j=overlays.begin(); j!=overlays.end(); ++j) + { + FS::Path opath = FS::dirname(path)/ *j/FS::basename(path); + if(FS::is_reg(opath)) + files.push_back(opath); + } + } } return files; @@ -255,6 +300,7 @@ Component::Loader::Loader(Component &c): { add("if_arch", &Loader::if_arch); add("if_feature", &Loader::if_feature); + add("overlay", &Loader::overlay); add("source", &Loader::source); add("install", &Component::install); add("install_map", &Loader::install_map); @@ -292,6 +338,11 @@ void Component::Loader::install_map() load_sub(obj.install_map, obj.package.get_source_directory()); } +void Component::Loader::overlay(const string &o) +{ + obj.overlays.push_back(o); +} + void Component::Loader::require(const string &n) { Package *req = obj.package.get_builder().get_package_manager().find_package(n); diff --git a/source/component.h b/source/component.h index 09767d3..3a743d0 100644 --- a/source/component.h +++ b/source/component.h @@ -28,6 +28,7 @@ public: void if_arch(const std::string &); void if_feature(const std::string &); void install_map(); + void overlay(const std::string &); void require(const std::string &); void source(const std::string &); void use(const std::string &); @@ -44,6 +45,7 @@ public: }; typedef std::list SourceList; + typedef std::list OverlayList; typedef std::list UseList; protected: @@ -51,6 +53,7 @@ protected: Type type; std::string name; SourceList sources; + OverlayList overlays; bool install; BuildInfo build_info; Package::Requirements requires; @@ -69,6 +72,8 @@ public: directories or individual files. */ const SourceList &get_sources() const { return sources; } + const OverlayList &get_overlays() const { return overlays; } + protected: /** Returns a list of all source files for the component. */ SourceList collect_source_files() const; @@ -89,6 +94,8 @@ public: const BuildInfo &get_build_info() const { return build_info; } + BuildInfo get_build_info_for_path(const Msp::FS::Path &) const; + void create_targets() const; }; diff --git a/source/installmap.cpp b/source/installmap.cpp index 22d92b1..942b932 100644 --- a/source/installmap.cpp +++ b/source/installmap.cpp @@ -1,4 +1,5 @@ #include +#include "component.h" #include "filetarget.h" #include "installmap.h" @@ -15,6 +16,17 @@ void InstallMap::add_mapping(const FS::Path &src, const FS::Path &inst) FS::Path InstallMap::get_install_location(const FileTarget &target) const { + const Component *comp = target.get_component(); + unsigned overlay_depth = 0; + if(comp && !comp->get_overlays().empty()) + { + const Component::OverlayList &overlays = comp->get_overlays(); + string last_dir = FS::basename(FS::dirname(target.get_path())); + for(Component::OverlayList::const_iterator i=overlays.begin(); i!=overlays.end(); ++i) + if(last_dir==*i) + overlay_depth = 1; + } + const FS::Path &source = target.get_path(); FS::Path install = target.get_install_location(); for(list::const_iterator i=entries.begin(); i!=entries.end(); ++i) @@ -25,7 +37,7 @@ FS::Path InstallMap::get_install_location(const FileTarget &target) const FS::Path install_base = FS::common_ancestor(install, i->install); if(install_base.size()>1) { - install = i->install/FS::dirname(source).subpath(i->source.size()); + install = i->install/source.subpath(i->source.size(), source_depth-1-overlay_depth); break; } } diff --git a/source/objectfile.cpp b/source/objectfile.cpp index 97e5255..321b954 100644 --- a/source/objectfile.cpp +++ b/source/objectfile.cpp @@ -65,6 +65,19 @@ void ObjectFile::find_dependencies(FileTarget *tgt) FS::Path displaced = tgt->get_path()/FS::relative(file->get_path(), rtgt->get_path()); if(Target *ddep = builder.get_vfs().get_target(displaced)) deps_to_add.push_back(ddep); + else + { + const Component *tcomp = file->get_component(); + const Component::OverlayList &overlays = tcomp->get_overlays(); + string last_dir = FS::basename(FS::dirname(displaced)); + for(Component::OverlayList::const_iterator j=overlays.begin(); j!=overlays.end(); ++j) + if(last_dir==*j) + { + displaced = displaced.subpath(0, displaced.size()-2)/FS::basename(file->get_path()); + if((ddep = builder.get_vfs().get_target(displaced))) + deps_to_add.push_back(ddep); + } + } } else deps_to_add.push_back(*i); -- 2.45.2