[M8] reusable libraries: install layout + cargoxx-path deps
This commit is contained in:
@@ -64,7 +64,10 @@ auto emit_header(const manifest::Manifest& m) -> std::string {
|
||||
"set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD \"d0edc3af-4c50-42ea-a356-e2862fe7a444\")\n"
|
||||
"set(CMAKE_CXX_MODULE_STD ON)\n"
|
||||
"\n"
|
||||
"project({} LANGUAGES CXX)\n"
|
||||
"project({} VERSION {} LANGUAGES CXX)\n"
|
||||
"\n"
|
||||
"include(GNUInstallDirs)\n"
|
||||
"include(CMakePackageConfigHelpers)\n"
|
||||
"\n"
|
||||
"# Generated by cargoxx — do not edit.\n"
|
||||
"# Source of truth: ../Cargoxx.toml\n"
|
||||
@@ -77,7 +80,7 @@ auto emit_header(const manifest::Manifest& m) -> std::string {
|
||||
"\n"
|
||||
"add_compile_options(-Wall -Wextra -Wpedantic -Wconversion "
|
||||
"-Wno-missing-field-initializers)\n",
|
||||
m.package.name, edition_to_int(m.package.edition));
|
||||
m.package.name, m.package.version, edition_to_int(m.package.edition));
|
||||
}
|
||||
|
||||
auto emit_find_packages(const std::vector<linkdb::Recipe>& recipes,
|
||||
@@ -153,9 +156,65 @@ auto any_recipe_is_catch2(const std::vector<linkdb::Recipe>& dev_recipes) -> boo
|
||||
return std::ranges::any_of(dev_recipes, recipe_is_catch2);
|
||||
}
|
||||
|
||||
auto emit_library_install_rules(const std::string& package_name) -> std::string {
|
||||
// Installs the static archive + module FILE_SET, exports targets,
|
||||
// generates Config.cmake + Version.cmake via configure_package_config_file,
|
||||
// and writes a basic pkg-config descriptor. Inline file(WRITE …) keeps the
|
||||
// .in templates self-contained in the generated CMakeLists.txt — no
|
||||
// out-of-tree files to manage.
|
||||
return std::format(
|
||||
"\n# ----- install + package-config + pkg-config -----\n"
|
||||
"install(TARGETS {0}\n"
|
||||
" EXPORT {0}Targets\n"
|
||||
" FILE_SET CXX_MODULES DESTINATION ${{CMAKE_INSTALL_INCLUDEDIR}}/{0}\n"
|
||||
" ARCHIVE DESTINATION ${{CMAKE_INSTALL_LIBDIR}})\n"
|
||||
"install(EXPORT {0}Targets\n"
|
||||
" FILE {0}Targets.cmake\n"
|
||||
" NAMESPACE {0}::\n"
|
||||
" DESTINATION ${{CMAKE_INSTALL_LIBDIR}}/cmake/{0})\n"
|
||||
"\n"
|
||||
"file(WRITE ${{CMAKE_CURRENT_BINARY_DIR}}/{0}Config.cmake.in [[\n"
|
||||
"@PACKAGE_INIT@\n"
|
||||
"include(CMakeFindDependencyMacro)\n"
|
||||
"include(\"${{CMAKE_CURRENT_LIST_DIR}}/{0}Targets.cmake\")\n"
|
||||
"check_required_components({0})\n"
|
||||
"]])\n"
|
||||
"configure_package_config_file(\n"
|
||||
" ${{CMAKE_CURRENT_BINARY_DIR}}/{0}Config.cmake.in\n"
|
||||
" ${{CMAKE_CURRENT_BINARY_DIR}}/{0}Config.cmake\n"
|
||||
" INSTALL_DESTINATION ${{CMAKE_INSTALL_LIBDIR}}/cmake/{0})\n"
|
||||
"write_basic_package_version_file(\n"
|
||||
" ${{CMAKE_CURRENT_BINARY_DIR}}/{0}ConfigVersion.cmake\n"
|
||||
" VERSION ${{PROJECT_VERSION}}\n"
|
||||
" COMPATIBILITY SameMajorVersion)\n"
|
||||
"install(FILES\n"
|
||||
" ${{CMAKE_CURRENT_BINARY_DIR}}/{0}Config.cmake\n"
|
||||
" ${{CMAKE_CURRENT_BINARY_DIR}}/{0}ConfigVersion.cmake\n"
|
||||
" DESTINATION ${{CMAKE_INSTALL_LIBDIR}}/cmake/{0})\n"
|
||||
"\n"
|
||||
"file(WRITE ${{CMAKE_CURRENT_BINARY_DIR}}/{0}.pc.in [[\n"
|
||||
"prefix=@CMAKE_INSTALL_PREFIX@\n"
|
||||
"exec_prefix=${{prefix}}\n"
|
||||
"libdir=${{prefix}}/${{CMAKE_INSTALL_LIBDIR}}\n"
|
||||
"includedir=${{prefix}}/${{CMAKE_INSTALL_INCLUDEDIR}}\n"
|
||||
"\n"
|
||||
"Name: @PROJECT_NAME@\n"
|
||||
"Version: @PROJECT_VERSION@\n"
|
||||
"Description: @PROJECT_NAME@\n"
|
||||
"Cflags: -I${{includedir}}\n"
|
||||
"Libs: -L${{libdir}} -l@PROJECT_NAME@\n"
|
||||
"]])\n"
|
||||
"configure_file(${{CMAKE_CURRENT_BINARY_DIR}}/{0}.pc.in\n"
|
||||
" ${{CMAKE_CURRENT_BINARY_DIR}}/{0}.pc @ONLY)\n"
|
||||
"install(FILES ${{CMAKE_CURRENT_BINARY_DIR}}/{0}.pc\n"
|
||||
" DESTINATION ${{CMAKE_INSTALL_LIBDIR}}/pkgconfig)\n",
|
||||
package_name);
|
||||
}
|
||||
|
||||
auto emit_library(const layout::Target& lib, const std::string& package_name,
|
||||
const std::vector<linkdb::Recipe>& recipes,
|
||||
const std::vector<std::string>& include_dirs,
|
||||
manifest::Edition edition,
|
||||
const fs::path& project_root) -> std::string {
|
||||
std::string out = "\n# ----- library target -----\n";
|
||||
out += std::format("add_library({} STATIC)\n", package_name);
|
||||
@@ -172,6 +231,11 @@ auto emit_library(const layout::Target& lib, const std::string& package_name,
|
||||
}
|
||||
}
|
||||
out += ")\n";
|
||||
// PUBLIC cxx_std_NN propagates the standard requirement onto the
|
||||
// exported IMPORTED target, so consumers `find_package`-ing this
|
||||
// library get the right standard for module BMI regeneration.
|
||||
out += std::format("target_compile_features({} PUBLIC cxx_std_{})\n",
|
||||
package_name, edition_to_int(edition));
|
||||
if (!include_dirs.empty()) {
|
||||
out += std::format("target_include_directories({} SYSTEM PRIVATE", package_name);
|
||||
for (const auto& d : include_dirs) {
|
||||
@@ -181,6 +245,8 @@ auto emit_library(const layout::Target& lib, const std::string& package_name,
|
||||
}
|
||||
out += link_block(package_name, "PUBLIC", false, package_name,
|
||||
collect_dep_targets(recipes));
|
||||
|
||||
out += emit_library_install_rules(package_name);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -190,10 +256,14 @@ auto emit_primary_binary(const layout::Target& bin, const std::string& package_n
|
||||
std::string out = "\n# ----- binary target -----\n";
|
||||
out += std::format("add_executable({}_bin {})\n", package_name,
|
||||
rel_to_build(bin.entry, project_root));
|
||||
out += std::format("set_target_properties({}_bin PROPERTIES OUTPUT_NAME {})\n",
|
||||
out += std::format("set_target_properties({}_bin PROPERTIES\n"
|
||||
" OUTPUT_NAME {}\n"
|
||||
" RUNTIME_OUTPUT_DIRECTORY \"${{CMAKE_BINARY_DIR}}/bin\")\n",
|
||||
package_name, package_name);
|
||||
out += link_block(std::format("{}_bin", package_name), "PRIVATE", has_lib, package_name,
|
||||
collect_dep_targets(recipes));
|
||||
out += std::format("install(TARGETS {}_bin RUNTIME DESTINATION ${{CMAKE_INSTALL_BINDIR}})\n",
|
||||
package_name);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -203,8 +273,13 @@ auto emit_extra_binary(const layout::Target& bin, const std::string& package_nam
|
||||
std::string out = std::format("\n# ----- binary target: {} -----\n", bin.name);
|
||||
out += std::format("add_executable({} {})\n", bin.name,
|
||||
rel_to_build(bin.entry, project_root));
|
||||
out += std::format("set_target_properties({} PROPERTIES\n"
|
||||
" RUNTIME_OUTPUT_DIRECTORY \"${{CMAKE_BINARY_DIR}}/bin\")\n",
|
||||
bin.name);
|
||||
out += link_block(bin.name, "PRIVATE", has_lib, package_name,
|
||||
collect_dep_targets(recipes));
|
||||
out += std::format("install(TARGETS {} RUNTIME DESTINATION ${{CMAKE_INSTALL_BINDIR}})\n",
|
||||
bin.name);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -335,7 +410,8 @@ auto cmake_lists(const GenerateInputs& in) -> std::string {
|
||||
|
||||
if (in.layout.library) {
|
||||
out += emit_library(*in.layout.library, pkg_name, in.recipes,
|
||||
in.manifest.build.include_dirs, in.project_root);
|
||||
in.manifest.build.include_dirs,
|
||||
in.manifest.package.edition, in.project_root);
|
||||
}
|
||||
|
||||
const auto* primary = find_primary_bin(in.layout);
|
||||
|
||||
Reference in New Issue
Block a user