GNUMakefile и gcc: разрешение порядка противоречивых требований "-std = c ++" - PullRequest
1 голос
/ 27 июня 2019

Многие пакеты в наши дни поставляются с утилитой конфигурации, которая помогает установить требования компилятора.При необходимости я могу привести более конкретные примеры, но Makefile, который ссылается на две библиотеки, может иметь что-то вроде:

CPPFLAGS += $(shell PackageA-config --cflags)
CPPFLAGS += $(shell PackageB-config --cflags)

%.o : %.cc 
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

Теперь давайте предположим, что PackageA требует как минимум c ++ 11, а PackageB требует c ++17, то есть PackageA-config --cflags даст -std=c++11, а PackageB-config --cflags даст -std=c++17.gcc будет использовать тот флаг, который пришел последним, и, поскольку все стандарты обратно совместимы, это нормально и модно.

Но что, если я напишу свой Makefile в «неправильном» порядке, так что PackageB будет первым?Теперь флаг PackageA -std=c++11 действительно используется, и компиляция не удалась.

Есть ли способ сказать gcc, чтобы он взял самый высокий из указанных флагов, а не просто использовал последний?Если нет, есть ли стандартный способ справиться с этой головной болью?Если все остальное не сработает, может ли какой-нибудь гуру придумать исправление, манипулируя переменной Makefile?

1 Ответ

3 голосов
/ 27 июня 2019

Есть куча строковых функций , которые очень полезно знать.

Вы можете отфильтровать флаг -std=:

filtered := $(filter -std=%,$(CPPFLAGS))

, а затем отсортировать его в лексическом порядке:

sorted := $(sort $(filtered))

А затем просто взять последний:

highest := $(lastword $(sorted))

Или все сразу:

best_std_version := $(lastword $(sort $(filter -std=%,$(CPPFLAGS))))

Это не будет работать, если одна из стандартных версий - 98. Это похоже на ошибку Y2K снова и снова.Но вы можете справиться с этим, отфильтровав его.

...