[M4] cargoxx build invokes nix+cmake
This commit is contained in:
@@ -14,10 +14,12 @@ auto cmd_new(const std::string& name, bool lib_only,
|
||||
const std::filesystem::path& parent_dir) -> util::Result<void>;
|
||||
|
||||
// Generates flake.nix, build/CMakeLists.txt, and Cargoxx.lock for the project
|
||||
// rooted at `project_root`. With `no_build = true`, only generates files; the
|
||||
// nix/cmake invocation lands at M4. `overlay_path` lets tests redirect the
|
||||
// linkdb overlay away from ~/.cache.
|
||||
// rooted at `project_root`. With `no_build = true`, only generates files;
|
||||
// otherwise also runs `nix develop -c cmake ...` to configure and build.
|
||||
// `target` (when set) is passed through to `cmake --build --target`.
|
||||
// `overlay_path` lets tests redirect the linkdb overlay away from ~/.cache.
|
||||
auto cmd_build(const std::filesystem::path& project_root, bool no_build, bool release,
|
||||
std::optional<std::string> target = std::nullopt,
|
||||
std::optional<std::filesystem::path> overlay_path = std::nullopt)
|
||||
-> util::Result<void>;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import cargoxx.layout;
|
||||
import cargoxx.linkdb;
|
||||
import cargoxx.lockfile;
|
||||
import cargoxx.codegen;
|
||||
import cargoxx.exec;
|
||||
|
||||
namespace cargoxx::cli {
|
||||
|
||||
@@ -72,7 +73,36 @@ auto synthesize_lockfile(const manifest::Manifest& m,
|
||||
|
||||
} // namespace
|
||||
|
||||
auto cmd_build(const fs::path& project_root, bool no_build, bool /*release*/,
|
||||
namespace {
|
||||
|
||||
auto run_nix_cmake(const fs::path& project_root, const std::vector<std::string>& cmake_args,
|
||||
std::string_view phase) -> util::Result<void> {
|
||||
std::vector<std::string> args{"develop", "--command", "cmake"};
|
||||
args.insert(args.end(), cmake_args.begin(), cmake_args.end());
|
||||
|
||||
auto r = exec::run("nix", args, exec::ExecOptions{
|
||||
.cwd = project_root,
|
||||
.env_overrides = {},
|
||||
.timeout = std::nullopt,
|
||||
.inherit_stdio = true,
|
||||
});
|
||||
if (!r) {
|
||||
return std::unexpected(r.error());
|
||||
}
|
||||
if (r->exit_code != 0) {
|
||||
return std::unexpected(util::Error{
|
||||
util::ErrorCode::BuildCmakeFailed,
|
||||
std::format("cmake {} failed (exit {})", phase, r->exit_code),
|
||||
"", std::nullopt, std::nullopt,
|
||||
});
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
auto cmd_build(const fs::path& project_root, bool no_build, bool release,
|
||||
std::optional<std::string> target,
|
||||
std::optional<fs::path> overlay_path) -> util::Result<void> {
|
||||
auto manifest_path = project_root / "Cargoxx.toml";
|
||||
auto m = manifest::parse(manifest_path);
|
||||
@@ -124,13 +154,31 @@ auto cmd_build(const fs::path& project_root, bool no_build, bool /*release*/,
|
||||
return std::unexpected(r.error());
|
||||
}
|
||||
|
||||
if (!no_build) {
|
||||
return std::unexpected(util::Error{
|
||||
util::ErrorCode::NotImplemented,
|
||||
"cargoxx build invocation is not implemented in this milestone",
|
||||
"rerun with --no-build to generate files only (full build lands at M4)",
|
||||
std::nullopt, std::nullopt,
|
||||
});
|
||||
if (no_build) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::string profile = release ? "release" : "debug";
|
||||
const std::string profile_cap = release ? "Release" : "Debug";
|
||||
const auto build_dir = std::format("build/{}", profile);
|
||||
|
||||
std::vector<std::string> configure_args{
|
||||
"-B", build_dir,
|
||||
"-S", "build",
|
||||
"-G", "Ninja",
|
||||
std::format("-DCMAKE_BUILD_TYPE={}", profile_cap),
|
||||
};
|
||||
if (auto r = run_nix_cmake(project_root, configure_args, "configure"); !r) {
|
||||
return std::unexpected(r.error());
|
||||
}
|
||||
|
||||
std::vector<std::string> build_args{"--build", build_dir};
|
||||
if (target) {
|
||||
build_args.push_back("--target");
|
||||
build_args.push_back(*target);
|
||||
}
|
||||
if (auto r = run_nix_cmake(project_root, build_args, "build"); !r) {
|
||||
return std::unexpected(r.error());
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
@@ -23,9 +23,12 @@ auto run(int argc, char** argv) -> int {
|
||||
"build", "Generate flake.nix and build/CMakeLists.txt; build with nix+cmake");
|
||||
bool build_no_build = false;
|
||||
bool build_release = false;
|
||||
std::string build_target;
|
||||
build_cmd->add_flag("--no-build", build_no_build,
|
||||
"Generate files only; do not invoke nix/cmake");
|
||||
build_cmd->add_flag("--release", build_release, "Build the release profile");
|
||||
build_cmd->add_option("--target", build_target,
|
||||
"Build a specific target (passed to cmake --build)");
|
||||
|
||||
try {
|
||||
app.parse(argc, argv);
|
||||
@@ -52,12 +55,20 @@ auto run(int argc, char** argv) -> int {
|
||||
}
|
||||
|
||||
if (*build_cmd) {
|
||||
auto r = cmd_build(cwd, build_no_build, build_release);
|
||||
std::optional<std::string> target;
|
||||
if (!build_target.empty()) {
|
||||
target = build_target;
|
||||
}
|
||||
auto r = cmd_build(cwd, build_no_build, build_release, target);
|
||||
if (!r) {
|
||||
std::cerr << util::format(r.error());
|
||||
return 1;
|
||||
}
|
||||
std::cout << " Generated flake.nix, build/CMakeLists.txt, Cargoxx.lock\n";
|
||||
if (build_no_build) {
|
||||
std::cout << " Generated flake.nix, build/CMakeLists.txt, Cargoxx.lock\n";
|
||||
} else {
|
||||
std::cout << " Built\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user