diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2020-07-10 07:25:34 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2020-07-10 11:07:49 +0200 |
commit | b92a060879caf1de82a60ff2980f70ac165ec1a8 (patch) | |
tree | c22949d5f5d3b49a1ef172a3a2312434ee289b6d | |
parent | fefcedab45d3e35782943faeee49478b5737c424 (diff) |
Add support for project-local importation
An import without a project name or with the same name as the importing
project's is now treated as importation from the same project.
For example, given the libhello project that exports the lib{hello} target, a
buildfile for an executable in the same project instead of doing something
like this:
include ../libhello/
exe{hello}: ../libhello/lib{hello}
Can now do this:
import lib = libhello%lib{hello}
Or:
import lib = lib{hello}
And then:
exe{hello}: $lib
Note that a target in project-local importation must still be exported in
the project's export stub. In other words, project-local importation goes
through the same mechanisms as normal import.
-rw-r--r-- | doc/manual.cli | 28 | ||||
-rw-r--r-- | libbuild2/file.cxx | 30 |
2 files changed, 47 insertions, 11 deletions
diff --git a/doc/manual.cli b/doc/manual.cli index ba0aa63..483c61d 100644 --- a/doc/manual.cli +++ b/doc/manual.cli @@ -2601,6 +2601,34 @@ If no \c{export} directive is executed in an export stub then the build system assumes that the target is not exported by the project and issues appropriate diagnostics.| +Let's revisit the executable \c{buildfile} with which we started this section. +Recall that it is for an executable that depends on a library which resides +in the same project: + +\ +include ../libhello/ # Include lib{hello}. + +exe{hello}: {hxx cxx}{**} ../libhello/lib{hello} +\ + +If \c{lib{hello\}} is exported by this project, then instead of manually +including its \c{buildfile} we can use \i{project-local importation}: + +\ +import lib = lib{hello} + +exe{hello}: {hxx cxx}{**} $lib +\ + +The main advantage of project-local importation over inclusion is the ability +to move things around without having to adjust locations in multiple places +(the only place we need to do it is the export stub). This advantage becomes +noticeable in more complex projects with a large number of components. + +\N|An import is project-local if the target being imported has no project +name. Note that the target must still be exported in the project's export +stub. In other words, project-local importation use the same mechanism as the +normal import.| \h#intro-lib|Library Exportation and Versioning| diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index 7ca8a91..f91dbbd 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -1838,6 +1838,9 @@ namespace build2 { tracer trace ("import_search"); + context& ctx (ibase.ctx); + scope& iroot (*ibase.root_scope ()); + // Depending on the target, we have four cases: // // 1. Ad hoc import: target is unqualified and is either absolute or is a @@ -1847,9 +1850,8 @@ namespace build2 // (e.g., because they don't know where it is), then they will have to // specify it with an explicit dir{} target type. // - // 2. Project-local import: target is unqualified. - // - // Note: this is still a TODO. + // 2. Project-local import: target is unqualified or the project name is + // the same as the importing project's. // // 3. Project-less import: target is empty-qualified. // @@ -1869,9 +1871,19 @@ namespace build2 return make_pair (move (tgt), optional<dir_path> (tgt.dir)); } else - fail (loc) << "importation of an unqualified target " << tgt << - info << "use empty project qualification to import a target " - << "without a project"; + { + // Project-local import. + // + const project_name& pn (project (iroot)); + + if (pn.empty ()) + fail (loc) << "project-local importation of target " << tgt + << " from an unnamed project"; + + tgt.proj = pn; + + return make_pair (move (tgt), optional<dir_path> (iroot.out_path ())); + } } // If the project name is empty then we simply return it as is to let @@ -1886,15 +1898,11 @@ namespace build2 if (tgt.absolute ()) fail (loc) << "absolute directory in imported target " << tgt; - context& ctx (ibase.ctx); - - // Otherwise, get the project name and convert the target to unqualified. + // Get the project name and convert the target to unqualified. // project_name proj (move (*tgt.proj)); tgt.proj = nullopt; - scope& iroot (*ibase.root_scope ()); - // Figure out the imported project's out_root. // optional<dir_path> out_root; |