} | } | ||||
} | } | ||||
} | } | ||||
return library_plan::create(lib, std::move(lp)); | |||||
return library_plan::create(lib, std::move(lp), pkg_man.namespace_ + "/" + lib.manifest().name); | |||||
} | } | ||||
package_plan prepare_one(state& st, const sdist_target& sd) { | package_plan prepare_one(state& st, const sdist_target& sd) { |
fs::create_directories(ar.out_path.parent_path()); | fs::create_directories(ar.out_path.parent_path()); | ||||
// Do it! | // Do it! | ||||
spdlog::info("[{}] Archive: {}", _name, out_relpath); | |||||
spdlog::info("[{}] Archive: {}", _qual_name, out_relpath); | |||||
auto&& [dur_ms, ar_res] = timed<std::chrono::milliseconds>([&] { return run_proc(ar_cmd); }); | auto&& [dur_ms, ar_res] = timed<std::chrono::milliseconds>([&] { return run_proc(ar_cmd); }); | ||||
spdlog::info("[{}] Archive: {} - {:n}ms", _name, out_relpath, dur_ms.count()); | |||||
spdlog::info("[{}] Archive: {} - {:n}ms", _qual_name, out_relpath, dur_ms.count()); | |||||
// Check, log, and throw | // Check, log, and throw | ||||
if (!ar_res.okay()) { | if (!ar_res.okay()) { | ||||
spdlog::error("Creating static library archive [{}] failed for '{}'", out_relpath, _name); | |||||
spdlog::error("Creating static library archive [{}] failed for '{}'", | |||||
out_relpath, | |||||
_qual_name); | |||||
spdlog::error("Subcommand FAILED: {}\n{}", quote_command(ar_cmd), ar_res.output); | spdlog::error("Subcommand FAILED: {}\n{}", quote_command(ar_cmd), ar_res.output); | ||||
throw_external_error< | throw_external_error< | ||||
errc::archive_failure>("Creating static library archive [{}] failed for '{}'", | errc::archive_failure>("Creating static library archive [{}] failed for '{}'", | ||||
out_relpath, | out_relpath, | ||||
_name); | |||||
_qual_name); | |||||
} | } | ||||
} | } |
class create_archive_plan { | class create_archive_plan { | ||||
/// The name of the archive. Not the filename, but the base name thereof | /// The name of the archive. Not the filename, but the base name thereof | ||||
std::string _name; | std::string _name; | ||||
/// The qualified name of the library, as it would appear in a libman-usage | |||||
std::string _qual_name; | |||||
/// The subdirectory in which the archive should be generated. | /// The subdirectory in which the archive should be generated. | ||||
fs::path _subdir; | fs::path _subdir; | ||||
/// The plans for compiling the constituent source files of this library | /// The plans for compiling the constituent source files of this library | ||||
* @param cfs The file compilation plans that will be collected together to | * @param cfs The file compilation plans that will be collected together to | ||||
* form the static library. | * form the static library. | ||||
*/ | */ | ||||
create_archive_plan(std::string_view name, path_ref subdir, std::vector<compile_file_plan> cfs) | |||||
create_archive_plan(std::string_view name, | |||||
std::string_view full_name, | |||||
path_ref subdir, | |||||
std::vector<compile_file_plan> cfs) | |||||
: _name(name) | : _name(name) | ||||
, _qual_name(full_name) | |||||
, _subdir(subdir) | , _subdir(subdir) | ||||
, _compile_files(std::move(cfs)) {} | , _compile_files(std::move(cfs)) {} | ||||
const auto link_command = env.toolchain.create_link_executable_command(spec); | const auto link_command = env.toolchain.create_link_executable_command(spec); | ||||
fs::create_directories(spec.output.parent_path()); | fs::create_directories(spec.output.parent_path()); | ||||
auto msg = fmt::format("[{}] Link: {:30}", | auto msg = fmt::format("[{}] Link: {:30}", | ||||
lib.name(), | |||||
lib.qualified_name(), | |||||
fs::relative(spec.output, env.output_root).string()); | fs::relative(spec.output, env.output_root).string()); | ||||
spdlog::info(msg); | spdlog::info(msg); | ||||
auto [dur_ms, proc_res] | auto [dur_ms, proc_res] |
using namespace dds; | using namespace dds; | ||||
library_plan library_plan::create(const library& lib, const library_build_params& params) { | |||||
library_plan library_plan::create(const library& lib, | |||||
const library_build_params& params, | |||||
std::optional<std::string_view> full_name) { | |||||
// Source files are kept in three groups: | // Source files are kept in three groups: | ||||
std::vector<source_file> app_sources; | std::vector<source_file> app_sources; | ||||
std::vector<source_file> test_sources; | std::vector<source_file> test_sources; | ||||
std::vector<source_file> lib_sources; | std::vector<source_file> lib_sources; | ||||
// Collect the source for this library. This will look for any compilable sources in the `src/` | |||||
// subdirectory of the library. | |||||
auto qual_name = std::string(full_name.value_or(lib.manifest().name)); | |||||
// Collect the source for this library. This will look for any compilable sources in the | |||||
// `src/` subdirectory of the library. | |||||
auto src_dir = lib.src_dir(); | auto src_dir = lib.src_dir(); | ||||
if (src_dir.exists()) { | if (src_dir.exists()) { | ||||
// Sort each source file between the three source arrays, depending on | // Sort each source file between the three source arrays, depending on | ||||
auto lib_compile_files = // | auto lib_compile_files = // | ||||
lib_sources // | lib_sources // | ||||
| ranges::views::transform([&](const source_file& sf) { | | ranges::views::transform([&](const source_file& sf) { | ||||
return compile_file_plan(compile_rules, | |||||
sf, | |||||
lib.manifest().name, | |||||
params.out_subdir / "obj"); | |||||
return compile_file_plan(compile_rules, sf, qual_name, params.out_subdir / "obj"); | |||||
}) | }) | ||||
| ranges::to_vector; | | ranges::to_vector; | ||||
std::optional<create_archive_plan> create_archive; | std::optional<create_archive_plan> create_archive; | ||||
if (!lib_compile_files.empty()) { | if (!lib_compile_files.empty()) { | ||||
create_archive.emplace(lib.manifest().name, | create_archive.emplace(lib.manifest().name, | ||||
qual_name, | |||||
params.out_subdir, | params.out_subdir, | ||||
std::move(lib_compile_files)); | std::move(lib_compile_files)); | ||||
} | } | ||||
exe_links, | exe_links, | ||||
compile_file_plan(rules, | compile_file_plan(rules, | ||||
source, | source, | ||||
lib.manifest().name, | |||||
qual_name, | |||||
params.out_subdir / "obj"), | params.out_subdir / "obj"), | ||||
subdir, | subdir, | ||||
source.path.stem().stem().string()}; | source.path.stem().stem().string()}; | ||||
} | } | ||||
// Done! | // Done! | ||||
return library_plan{lib, std::move(create_archive), std::move(link_executables)}; | |||||
return library_plan{lib, qual_name, std::move(create_archive), std::move(link_executables)}; | |||||
} | } |
class library_plan { | class library_plan { | ||||
/// The underlying library object | /// The underlying library object | ||||
library _lib; | library _lib; | ||||
/// The qualified name of the library | |||||
std::string _qual_name; | |||||
/// The `create_archive_plan` for this library, if applicable | /// The `create_archive_plan` for this library, if applicable | ||||
std::optional<create_archive_plan> _create_archive; | std::optional<create_archive_plan> _create_archive; | ||||
/// The executables that should be linked as part of this library's build | /// The executables that should be linked as part of this library's build | ||||
* @param exes The `link_executable_plan` objects for this library. | * @param exes The `link_executable_plan` objects for this library. | ||||
*/ | */ | ||||
library_plan(library lib, | library_plan(library lib, | ||||
std::string_view full_name, | |||||
std::optional<create_archive_plan> ar, | std::optional<create_archive_plan> ar, | ||||
std::vector<link_executable_plan> exes) | std::vector<link_executable_plan> exes) | ||||
: _lib(std::move(lib)) | : _lib(std::move(lib)) | ||||
, _qual_name(full_name) | |||||
, _create_archive(std::move(ar)) | , _create_archive(std::move(ar)) | ||||
, _link_exes(std::move(exes)) {} | , _link_exes(std::move(exes)) {} | ||||
* Get the name of the library | * Get the name of the library | ||||
*/ | */ | ||||
auto& name() const noexcept { return _lib.manifest().name; } | auto& name() const noexcept { return _lib.manifest().name; } | ||||
/** | |||||
* Get the qualified name of the library, as if for a libman usage requirement | |||||
*/ | |||||
auto& qualified_name() const noexcept { return _qual_name; } | |||||
/** | /** | ||||
* The directory that defines the source root of the library. | * The directory that defines the source root of the library. | ||||
*/ | */ | ||||
* @param lib The `library` object from which we will inherit several properties. | * @param lib The `library` object from which we will inherit several properties. | ||||
* @param params Parameters controlling the build of the library. i.e. if we create tests, | * @param params Parameters controlling the build of the library. i.e. if we create tests, | ||||
* enable warnings, etc. | * enable warnings, etc. | ||||
* @param full_name Optionally, provide the fully-qualified name of the library that is being | |||||
* built | |||||
* | * | ||||
* The `lib` parameter defines the usage requirements of this library, and they are looked up in | * The `lib` parameter defines the usage requirements of this library, and they are looked up in | ||||
* the `ureqs` map. If there are any missing requirements, an exception will be thrown. | * the `ureqs` map. If there are any missing requirements, an exception will be thrown. | ||||
*/ | */ | ||||
static library_plan create(const library& lib, const library_build_params& params); | |||||
static library_plan create(const library& lib, | |||||
const library_build_params& params, | |||||
std::optional<std::string_view> full_name); | |||||
}; | }; | ||||
} // namespace dds | } // namespace dds |