diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-08-02 11:18:38 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-08-02 11:33:51 +0200 |
commit | e65c406301c3a7b30174f8706ba39584e80ddf25 (patch) | |
tree | 39ab598476f4965616979f498e016e3f7913008c | |
parent | e8ef2fbd339afd8113bd92d371bc49d7d570c32f (diff) |
Save module map to pkg-config files
-rw-r--r-- | build2/cc/compile.cxx | 6 | ||||
-rw-r--r-- | build2/cc/pkgconfig.cxx | 50 | ||||
-rw-r--r-- | build2/install/rule.cxx | 25 | ||||
-rw-r--r-- | build2/install/utility.hxx | 6 | ||||
-rw-r--r-- | build2/target.hxx | 9 |
5 files changed, 91 insertions, 5 deletions
diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx index 6c3cc4c..9f36e8b 100644 --- a/build2/cc/compile.cxx +++ b/build2/cc/compile.cxx @@ -2766,8 +2766,8 @@ namespace build2 // name for each mxx{} explicitly. This will be a major pain, however. // Another would be to require encoding of the module name in the // interface unit file name. For example, hello.core -> hello-core.mxx. - // This is better but will still too restrictive: some will want to call - // it hello_core.mxx or HelloCore.mxx (because that's their file naming + // This is better but still too restrictive: some will want to call it + // hello_core.mxx or HelloCore.mxx (because that's their file naming // convention) or place it in a subdirectory, say, hello/core.mxx. // // In the above examples one common theme about all the file names is @@ -3010,6 +3010,8 @@ namespace build2 // available. // // @@ MOD: BMI compatibility check. + // @@ UTL: we need to (recursively) see through libux{} (and + // also in pkgconfig_save()). // if (bt != nullptr && (bt->is_a<bmis> () || diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx index 8d0ea25..d320060 100644 --- a/build2/cc/pkgconfig.cxx +++ b/build2/cc/pkgconfig.cxx @@ -733,6 +733,56 @@ namespace build2 os << endl; + // If we have modules, list them in the modules variable. This code + // is pretty similar to compiler::search_modules(). + // + if (modules) + { + os << endl + << "modules ="; + + for (const target* pt: l.prerequisite_targets) + { + // @@ UTL: we need to (recursively) see through libux{} (and + // also in search_modules()). + // + if (pt != nullptr && + (pt->is_a<bmis> () || + pt->is_a<bmia> () || + pt->is_a<bmie> ())) + { + // What we have is a binary module interface. What we need is + // a module interface source it was built from. We assume it's + // the first mxx{} target that we see. + // + const target* mt (nullptr); + for (const target* t: pt->prerequisite_targets) + { + if ((mt = t->is_a (*x_mod))) + break; + } + + // Can/should there be a bmi{} without mxx{}? Can't think of a + // reason. + // + assert (mt != nullptr); + + path p (install::resolve_file (mt->as<file> ())); + + if (p.empty ()) // Not installed. + continue; + + const string& n (cast<string> (pt->vars[c_module_name])); + + // Module name shouldn't require escaping. + // + os << ' ' << n << '=' << escape (p.string ()); + } + } + + os << endl; + } + os.close (); arm.cancel (); } diff --git a/build2/install/rule.cxx b/build2/install/rule.cxx index c76800a..1f14fce 100644 --- a/build2/install/rule.cxx +++ b/build2/install/rule.cxx @@ -399,6 +399,29 @@ namespace build2 return move (resolve (t, move (d)).back ().dir); } + path + resolve_file (const file& f) + { + // Note: similar logic to perform_install(). + // + const path* p (lookup_install<path> (f, "install")); + + if (p == nullptr) // Not installable. + return path (); + + bool n (!p->to_directory ()); + dir_path d (n ? p->directory () : path_cast<dir_path> (*p)); + + install_dirs ids (resolve (f, d)); + if (auto l = f["install.subdirs"]) + { + if (cast<bool> (l)) + resolve_subdir (ids, f, f.base_scope (), l); + } + + return ids.back ().dir / (n ? p->leaf () : f.path ().leaf ()); + } + // On Windows we use MSYS2 install.exe and MSYS2 by default ignores // filesystem permissions (noacl mount option). And this means, for // example, that .exe that we install won't be runnable by Windows (MSYS2 @@ -631,6 +654,8 @@ namespace build2 auto install_target = [this] (const file& t, const path& p, bool verbose) { + // Note: similar logic to resolve_file(). + // bool n (!p.to_directory ()); dir_path d (n ? p.directory () : path_cast<dir_path> (p)); diff --git a/build2/install/utility.hxx b/build2/install/utility.hxx index 21c0c44..173b25c 100644 --- a/build2/install/utility.hxx +++ b/build2/install/utility.hxx @@ -9,6 +9,7 @@ #include <build2/utility.hxx> #include <build2/scope.hxx> +#include <build2/target.hxx> namespace build2 { @@ -57,6 +58,11 @@ namespace build2 // dir_path resolve_dir (const target&, dir_path); // rule.cxx + + // Resolve file installation path returning empty path if not installable. + // + path + resolve_file (const file&); // rule.cxx } } diff --git a/build2/target.hxx b/build2/target.hxx index 3af533f..94fb800 100644 --- a/build2/target.hxx +++ b/build2/target.hxx @@ -640,8 +640,9 @@ namespace build2 // Target type info and casting. // public: - bool - is_a (const target_type& tt) const {return type ().is_a (tt);} + const target* + is_a (const target_type& tt) const { + return type ().is_a (tt) ? this : nullptr;} template <typename T> T* @@ -871,7 +872,9 @@ namespace build2 bool is_a (const target_type_type& tt) const { - return target != nullptr ? target->is_a (tt) : prerequisite.is_a (tt); + return target != nullptr + ? target->is_a (tt) != nullptr + : prerequisite.is_a (tt); } prerequisite_key |