Skip to content

Commit bce2e78

Browse files
authored
feat(manifest): support inherit-mode: append (#1191)
1 parent 7b0057b commit bce2e78

File tree

2 files changed

+122
-13
lines changed

2 files changed

+122
-13
lines changed

cabin.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ compdb = true # always build comp DB on dev
3030
lto = true
3131

3232
[profile.test]
33-
cxxflags = ["-pedantic-errors", "-Wall", "-Wextra", "-Wpedantic", "-fno-rtti", "-fsanitize=undefined"]
33+
cxxflags = ["-fsanitize=undefined"]
3434
ldflags = ["-fsanitize=undefined"]
3535
compdb = false
3636

src/Manifest.cc

Lines changed: 121 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,21 +218,66 @@ parseReleaseProfile(
218218
));
219219
}
220220

221+
enum class InheritMode : uint8_t {
222+
Append,
223+
Overwrite,
224+
};
225+
226+
static Result<InheritMode>
227+
parseInheritMode(std::string_view mode) noexcept {
228+
if (mode == "append") {
229+
return Ok(InheritMode::Append);
230+
} else if (mode == "overwrite") {
231+
return Ok(InheritMode::Overwrite);
232+
} else {
233+
Bail("invalid inherit-mode: `{}`", mode);
234+
}
235+
}
236+
237+
static std::vector<std::string>
238+
inheritFlags(
239+
const InheritMode inheritMode, const std::vector<std::string>& baseFlags,
240+
const std::vector<std::string>& newFlags
241+
) noexcept {
242+
if (newFlags.empty()) {
243+
return baseFlags; // No change, use base flags.
244+
}
245+
246+
if (inheritMode == InheritMode::Append) {
247+
// Append new flags to the base flags.
248+
std::vector<std::string> merged = baseFlags;
249+
merged.insert(merged.end(), newFlags.begin(), newFlags.end());
250+
return merged;
251+
} else {
252+
// Overwrite base flags with new flags.
253+
return newFlags;
254+
}
255+
}
256+
221257
// Inherits from `dev`.
222258
static Result<Profile>
223259
parseTestProfile(const toml::value& val, const Profile& devProfile) noexcept {
224260
static constexpr const char* key = "test";
225261

226-
auto cxxflags = Try(validateFlags(
227-
"cxxflags", toml::find_or<std::vector<std::string>>(
228-
val, "profile", key, "cxxflags", devProfile.cxxflags
229-
)
230-
));
231-
auto ldflags = Try(validateFlags(
232-
"ldflags", toml::find_or<std::vector<std::string>>(
233-
val, "profile", key, "ldflags", devProfile.ldflags
234-
)
262+
const InheritMode inheritMode = Try(parseInheritMode(
263+
toml::find_or<std::string>(val, "profile", key, "inherit-mode", "append")
235264
));
265+
std::vector<std::string> cxxflags = inheritFlags(
266+
inheritMode, devProfile.cxxflags,
267+
Try(validateFlags(
268+
"cxxflags", toml::find_or_default<std::vector<std::string>>(
269+
val, "profile", key, "cxxflags"
270+
)
271+
))
272+
);
273+
std::vector<std::string> ldflags = inheritFlags(
274+
inheritMode, devProfile.ldflags,
275+
Try(validateFlags(
276+
"ldflags", toml::find_or_default<std::vector<std::string>>(
277+
val, "profile", key, "ldflags"
278+
)
279+
))
280+
);
236281
const auto lto =
237282
toml::find_or<bool>(val, "profile", key, "lto", devProfile.lto);
238283
const auto debug =
@@ -918,7 +963,7 @@ testParseProfiles() {
918963
opt-level = 1
919964
920965
[profile.test]
921-
cxxflags = ["-fno-rtti"]
966+
opt-level = 3
922967
)"_toml;
923968

924969
const Profile devExpected(
@@ -932,9 +977,9 @@ testParseProfiles() {
932977
/*compDb=*/false, /*optLevel=*/2 // here, the default is 3
933978
);
934979
const Profile testExpected(
935-
/*cxxflags=*/{ "-fno-rtti" }, /*ldflags=*/{}, /*lto=*/false,
980+
/*cxxflags=*/{}, /*ldflags=*/{}, /*lto=*/false,
936981
/*debug=*/true,
937-
/*compDb=*/false, /*optLevel=*/1
982+
/*compDb=*/false, /*optLevel=*/3
938983
);
939984

940985
const auto profiles = parseProfiles(overwrite).unwrap();
@@ -943,6 +988,70 @@ testParseProfiles() {
943988
assertEq(profiles.at(BuildProfile::Release), relExpected);
944989
assertEq(profiles.at(BuildProfile::Test), testExpected);
945990
}
991+
{
992+
const toml::value append = R"(
993+
[profile.dev]
994+
cxxflags = ["-A"]
995+
996+
[profile.test]
997+
cxxflags = ["-B"]
998+
)"_toml;
999+
1000+
const Profile devExpected(
1001+
/*cxxflags=*/{ "-A" }, /*ldflags=*/{}, /*lto=*/false,
1002+
/*debug=*/true,
1003+
/*compDb=*/false, /*optLevel=*/0
1004+
);
1005+
const Profile testExpected(
1006+
/*cxxflags=*/{ "-A", "-B" }, /*ldflags=*/{}, /*lto=*/false,
1007+
/*debug=*/true,
1008+
/*compDb=*/false, /*optLevel=*/0
1009+
);
1010+
1011+
const auto profiles = parseProfiles(append).unwrap();
1012+
assertEq(profiles.size(), 3UL);
1013+
assertEq(profiles.at(BuildProfile::Dev), devExpected);
1014+
assertEq(profiles.at(BuildProfile::Release), relProfileDefault);
1015+
assertEq(profiles.at(BuildProfile::Test), testExpected);
1016+
}
1017+
{
1018+
const toml::value overwrite = R"(
1019+
[profile.dev]
1020+
cxxflags = ["-A"]
1021+
1022+
[profile.test]
1023+
inherit-mode = "overwrite"
1024+
cxxflags = ["-B"]
1025+
)"_toml;
1026+
1027+
const Profile devExpected(
1028+
/*cxxflags=*/{ "-A" }, /*ldflags=*/{}, /*lto=*/false,
1029+
/*debug=*/true,
1030+
/*compDb=*/false, /*optLevel=*/0
1031+
);
1032+
const Profile testExpected(
1033+
/*cxxflags=*/{ "-B" }, /*ldflags=*/{}, /*lto=*/false,
1034+
/*debug=*/true,
1035+
/*compDb=*/false, /*optLevel=*/0
1036+
);
1037+
1038+
const auto profiles = parseProfiles(overwrite).unwrap();
1039+
assertEq(profiles.size(), 3UL);
1040+
assertEq(profiles.at(BuildProfile::Dev), devExpected);
1041+
assertEq(profiles.at(BuildProfile::Release), relProfileDefault);
1042+
assertEq(profiles.at(BuildProfile::Test), testExpected);
1043+
}
1044+
{
1045+
const toml::value incorrect = R"(
1046+
[profile.test]
1047+
inherit-mode = "UNKNOWN"
1048+
)"_toml;
1049+
1050+
assertEq(
1051+
parseProfiles(incorrect).unwrap_err()->what(),
1052+
"invalid inherit-mode: `UNKNOWN`"
1053+
);
1054+
}
9461055
}
9471056

9481057
static void

0 commit comments

Comments
 (0)