Skip to content

Commit 5eff968

Browse files
committed
feat(workspace): allow duplicate names in different packages in a workspace
1 parent e6b6e01 commit 5eff968

18 files changed

Lines changed: 378 additions & 76 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.17)
2-
project(cppship VERSION 0.8.1)
2+
project(cppship VERSION 0.8.2)
33

44
# cpp std
55
set(CMAKE_CXX_STANDARD 20)

cppship.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cppship"
3-
version = "0.8.1"
3+
version = "0.8.2"
44
authors = []
55
std = 20
66

include/cppship/cmake/naming.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,18 @@ namespace cppship::cmake {
77

88
class NameTargetMapper {
99
public:
10+
explicit NameTargetMapper(std::string_view package)
11+
: mPackage(package)
12+
{
13+
}
14+
15+
std::string binary(std::string_view name);
1016
std::string test(std::string_view name);
1117
std::string example(std::string_view name);
1218
std::string bench(std::string_view name);
19+
20+
private:
21+
std::string mPackage;
1322
};
1423

15-
}
24+
}

include/cppship/cmd/bench.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace cppship::cmd {
99

1010
struct BenchOptions {
1111
Profile profile = Profile::release;
12-
std::optional<std::string> target;
12+
std::optional<std::string> name;
1313
std::optional<std::string> package;
1414
};
1515

include/cppship/cmd/test.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace cppship::cmd {
99

1010
struct TestOptions {
1111
Profile profile = Profile::debug;
12-
std::optional<std::string> target;
12+
std::optional<std::string> name;
1313
std::optional<std::string> package;
1414
std::optional<std::string> name_regex;
1515
bool rerun_failed = false;

include/cppship/core/layout.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#pragma once
22

3-
#include "cppship/util/fs.h"
43
#include <map>
54
#include <optional>
65
#include <set>
76
#include <vector>
87

8+
#include "cppship/util/fs.h"
9+
910
namespace cppship {
1011

1112
struct Target {
@@ -18,6 +19,8 @@ class Layout {
1819
public:
1920
Layout(const fs::path& root, std::string_view name);
2021

22+
std::string_view package() const { return mName; }
23+
2124
std::set<fs::path> all_files() const;
2225

2326
std::optional<Target> lib() const;
@@ -56,4 +59,4 @@ class Layout {
5659
std::map<std::string, Target, std::less<>> mTests;
5760
};
5861

59-
}
62+
}

include/cppship/core/workspace.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ class Workspace {
2929

3030
auto layouts() const { return ranges::views::values(packages_); }
3131

32+
const Layout* layout(std::string_view package) const;
33+
3234
private:
3335
fs::path root_;
3436

3537
// if there is only one package, the key is fs::path{}
3638
std::map<fs::path, Layout> packages_;
3739
};
3840

39-
// Workspace is not full supported now, use this to enforce default layout.
4041
const Layout& enforce_default_package(const Workspace& workspace);
4142

4243
}

lib/cmake/generator.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,12 @@ void CmakeGenerator::add_app_sources_()
197197
boost::replace_all_copy(boost::to_upper_copy(std::string { mName }), "-", "_")),
198198
};
199199

200+
NameTargetMapper mapper(mName);
200201
for (const auto& bin : mLayout->binaries()) {
202+
const auto target = mapper.binary(bin.name);
201203
cmake::CmakeBin gen({
202-
.name = bin.name,
204+
.name = target,
205+
.name_alias = bin.name,
203206
.sources = bin.sources,
204207
.lib = mLib,
205208
.deps = mDeps,
@@ -208,7 +211,7 @@ void CmakeGenerator::add_app_sources_()
208211
});
209212

210213
gen.build(mOut);
211-
mBinaryTargets.emplace(bin.name);
214+
mBinaryTargets.emplace(target);
212215
}
213216
}
214217

@@ -250,7 +253,7 @@ void CmakeGenerator::add_benches_()
250253
find_package(benchmark REQUIRED)
251254
)";
252255

253-
NameTargetMapper mapper;
256+
NameTargetMapper mapper(mName);
254257
auto deps = mDevDeps;
255258
deps.push_back({
256259
.cmake_package = "benchmark",
@@ -264,6 +267,7 @@ find_package(benchmark REQUIRED)
264267
.sources = bin.sources,
265268
.lib = mLib,
266269
.deps = deps,
270+
.runtime_dir = "benches",
267271
});
268272

269273
gen.build(mOut);
@@ -278,13 +282,12 @@ void CmakeGenerator::add_examples_()
278282
return;
279283
}
280284

281-
NameTargetMapper mapper;
285+
NameTargetMapper mapper(mName);
282286
for (const auto& bin : examples) {
283287
const auto target = mapper.example(bin.name);
284288

285289
cmake::CmakeBin gen({
286290
.name = target,
287-
.name_alias = bin.name,
288291
.sources = bin.sources,
289292
.lib = mLib,
290293
.deps = mDevDeps,
@@ -308,13 +311,17 @@ void CmakeGenerator::add_test_sources_()
308311
find_package(GTest REQUIRED)
309312
)";
310313

311-
NameTargetMapper mapper;
314+
NameTargetMapper mapper(mName);
312315
for (const auto& test : tests) {
313316
const auto target = mapper.test(test.name);
314317

315318
mOut << '\n'
316319
<< fmt::format("add_executable({} {})\n", target, test.sources.begin()->generic_string())
317-
<< fmt::format("target_link_libraries({} PRIVATE GTest::gtest_main)\n", target);
320+
<< fmt::format("target_link_libraries({} PRIVATE GTest::gtest_main)\n", target)
321+
<< fmt::format(
322+
R"(set_target_properties({} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${{CMAKE_BINARY_DIR}}/tests"))",
323+
target)
324+
<< '\n';
318325

319326
if (mLib) {
320327
mOut << fmt::format("target_link_libraries({} PRIVATE {})\n", target, *mLib);
@@ -323,7 +330,7 @@ find_package(GTest REQUIRED)
323330
mOut << fmt::format("target_link_libraries({} PRIVATE {})\n", target, boost::join(dep.cmake_targets, " "));
324331
}
325332

326-
mOut << fmt::format("add_test({} {})\n", target, target);
333+
mOut << fmt::format("add_test(NAME {} COMMAND {})\n", target, target);
327334
mOut << fmt::format("set_tests_properties({} PROPERTIES LABELS {})\n", target, mName);
328335

329336
mTestTargets.emplace(target);

lib/cmake/naming.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
using namespace cppship::cmake;
66

7-
std::string NameTargetMapper::test(std::string_view name) { return fmt::format("{}_test", name); }
7+
std::string NameTargetMapper::binary(std::string_view name) { return fmt::format("{}_bin", name); }
88

9-
std::string NameTargetMapper::example(std::string_view name) { return fmt::format("{}_example", name); }
9+
std::string NameTargetMapper::test(std::string_view name) { return fmt::format("{}_{}_test", mPackage, name); }
1010

11-
std::string NameTargetMapper::bench(std::string_view name) { return fmt::format("{}_bench", name); }
11+
std::string NameTargetMapper::example(std::string_view name) { return fmt::format("{}_{}_example", mPackage, name); }
12+
13+
std::string NameTargetMapper::bench(std::string_view name) { return fmt::format("{}_{}_bench", mPackage, name); }

lib/cmd/bench.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44

55
#include <boost/process/system.hpp>
66
#include <gsl/narrow>
7-
#include <range/v3/algorithm/all_of.hpp>
87
#include <range/v3/range/conversion.hpp>
9-
#include <range/v3/view.hpp>
8+
#include <range/v3/view/filter.hpp>
109
#include <spdlog/spdlog.h>
1110

1211
#include "cppship/cmake/msvc.h"
@@ -24,7 +23,7 @@ namespace {
2423

2524
int run_one_bench(const cmd::BuildContext& ctx, const std::string_view bench)
2625
{
27-
const auto bin = ctx.profile_dir / msvc::fix_bin_path(ctx, bench);
26+
const auto bin = ctx.profile_dir / kBenchesPath / msvc::fix_bin_path(ctx, bench);
2827
const auto cmd = bin.string();
2928
status("bench", "{}", cmd);
3029
return boost::process::system(cmd);
@@ -34,17 +33,23 @@ int run_one_bench(const cmd::BuildContext& ctx, const std::string_view bench)
3433

3534
int cmd::run_bench(const BenchOptions& options)
3635
{
37-
NameTargetMapper mapper;
38-
3936
BuildContext ctx(options.profile);
4037
BuildOptions build_options { .profile = options.profile };
41-
if (options.target) {
42-
if (ranges::all_of(
43-
ctx.workspace.layouts(), [&](const auto& layout) { return !layout.bench(*options.target); })) {
44-
throw Error { fmt::format("bench `{}` not found", *options.target) };
38+
if (options.name) {
39+
const auto layouts = ctx.workspace.layouts()
40+
| filter([&](const Layout& layout) { return layout.bench(*options.name).has_value(); })
41+
| ranges::to<std::vector>();
42+
if (layouts.empty()) {
43+
throw Error { fmt::format("bench `{}` not found", *options.name) };
44+
}
45+
if (layouts.size() > 1) {
46+
throw Error { fmt::format("too many benches with name {}, eg. {}, {}",
47+
*options.name,
48+
layouts.front().package(),
49+
layouts.back().package()) };
4550
}
4651

47-
build_options.cmake_target = mapper.bench(*options.target);
52+
build_options.cmake_target = NameTargetMapper(layouts.front().package()).bench(*options.name);
4853
} else {
4954
build_options.package = options.package;
5055
build_options.groups.insert(BuildGroup::benches);
@@ -61,6 +66,8 @@ int cmd::run_bench(const BenchOptions& options)
6166

6267
for (const auto& layout : ctx.workspace.layouts()) {
6368
for (const auto& bench : layout.benches()) {
69+
NameTargetMapper mapper(layout.package());
70+
6471
const int res = run_one_bench(ctx, mapper.bench(bench.name));
6572
if (res != 0) {
6673
result = res;

0 commit comments

Comments
 (0)