Merge pull request #6544 from jakubtomsu/target-feature-fix

Fix target feature lookup, canonicalize target_features_set
This commit is contained in:
gingerBill
2026-04-10 13:02:20 +01:00
committed by GitHub
3 changed files with 44 additions and 19 deletions

View File

@@ -2215,18 +2215,18 @@ gb_internal bool check_target_feature_is_enabled(String const &feature, String *
}
if (feature_str == "") break;
if (!string_set_exists(&build_context.target_features_set, str)) {
String plus_str = concatenate_strings(temporary_allocator(), make_string_c("+"), feature_str);
if (want_enabled && !string_set_exists(&build_context.target_features_set, plus_str)) {
if (not_enabled) *not_enabled = str;
return false;
}
}
String plus_str = concatenate_strings(temporary_allocator(), make_string_c("+"), feature_str);
String minus_str = concatenate_strings(temporary_allocator(), make_string_c("-"), feature_str);
if (!want_enabled && !string_set_exists(&build_context.target_features_set, minus_str)) {
bool has_raw = string_set_exists(&build_context.target_features_set, feature_str);
bool has_plus = string_set_exists(&build_context.target_features_set, plus_str);
bool has_minus = string_set_exists(&build_context.target_features_set, minus_str);
// NOTE(jakubtomsu): this way "feature" and "+feature" is ALWAYS equivalent,
// and also allows the minus sign to do a final override.
bool is_enabled = (has_plus || has_raw) && !has_minus;
if (want_enabled != is_enabled) {
if (not_enabled) *not_enabled = str;
return false;
}

View File

@@ -3973,15 +3973,16 @@ int main(int arg_count, char const **arg_ptr) {
for (;;) {
String item = string_split_iterator(&target_it, ',');
if (item == "") break;
if (*item.text == '+' || *item.text == '-') {
item.text++;
item.len--;
String stripped_item = item;
if (*stripped_item.text == '+' || *stripped_item.text == '-') {
stripped_item.text++;
stripped_item.len--;
}
String invalid;
if (!check_target_feature_is_valid_for_target_arch(item, &invalid) && item != str_lit("help")) {
if (item != str_lit("?")) {
if (!check_target_feature_is_valid_for_target_arch(stripped_item, &invalid) && stripped_item != str_lit("help")) {
if (stripped_item != str_lit("?")) {
gb_printf_err("Unkown target feature '%.*s'.\n", LIT(invalid));
}
gb_printf("Possible -target-features for target %.*s are:\n", LIT(target_arch_names[build_context.metrics.arch]));
@@ -4005,8 +4006,25 @@ int main(int arg_count, char const **arg_ptr) {
return 1;
}
string_set_add(&build_context.target_features_set, item);
// Ensure the feature name always has +/- prefix. If there isn't, default to '+'
String feature_str = item;
if (*feature_str.text != '+' && *feature_str.text != '-') {
feature_str = concatenate_strings(temporary_allocator(), make_string_c("+"), feature_str);
}
// Ensure there is only a single entry for each feature in the target set.
// If the negative exists, override the existing value with the current one.
String neg_feature_str = clone_string(temporary_allocator(), feature_str);
switch (*neg_feature_str.text) {
case '+': *neg_feature_str.text = '-'; break;
case '-': *neg_feature_str.text = '+'; break;
default: GB_ASSERT(false); break;
}
string_set_remove(&build_context.target_features_set, neg_feature_str);
string_set_add(&build_context.target_features_set, feature_str);
}
}

View File

@@ -508,6 +508,13 @@ gb_internal String filename_without_directory(String s) {
return substring(s, gb_max(j+1, 0), s.len);
}
gb_internal String clone_string(gbAllocator a, String const &x) {
u8 *data = gb_alloc_array(a, u8, x.len+1);
gb_memmove(data, x.text, x.len);
data[x.len] = 0;
return make_string(data, x.len);
}
gb_internal String concatenate_strings(gbAllocator a, String const &x, String const &y) {
isize len = x.len+y.len;
u8 *data = gb_alloc_array(a, u8, len+1);