CMake автоматически устанавливает CXX при первом запуске - PullRequest
0 голосов
/ 10 марта 2020

У меня есть проект на C ++, в котором я не хочу указывать компилятор «по умолчанию», поскольку его нужно компилировать с использованием множества разных компиляторов в разных контекстах. (В модульном тестировании и сквозном тестировании я тестирую его с помощью нескольких разных компиляторов.)

Я попытался реализовать это в CMake, потребовав от пользователя установить переменную среды CXX до начальная конфигурация CMake (выполняется cmake). (У меня также есть файл для сохранения значения, чтобы гарантировать, что любой последующий вызов make будет иметь то же значение, что и набор CXX, но это не имеет отношения к остальной части вопроса.)

Однако это на самом деле не работает. Вот минимальный пример и выходные данные выполнения.

Файл конфигурации CMake:

project(test)

if(DEFINED ENV{CXX})
    message("\$CXX = ${CXX}")
else()
    message(SEND_ERROR "\$CXX must be defined by the user to compile this project.")
endif()

add_executable(test)

Первое выполнение cmake:

-- The C compiler identification is GNU 4.3.4
-- The CXX compiler identification is GNU 4.3.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
$CXX =
-- Configuring done
CMake Error at CMakeLists.txt:9 (add_executable):
  No SOURCES given to target: test


-- Build files have been written to: /hnfs/torcfs03n06a/vol/ret_users_sasquire/inactive/bugs/cmake

Второй вызов cmake в том же каталоге (без очистки):

CMake Error at CMakeLists.txt:6 (message):
  $CXX must be defined to compile this project.


-- Configuring incomplete, errors occurred!

Таким образом, определение того, определен ли CXX, явно работает второй раз, но не в первый раз.

Два вопроса:

  1. Как должен Я это реализую?

  2. Я думаю, что это довольно разумное поведение для cmake для установки CXX внутри, если это не было установлено пользователем, и я подозреваю, что это происходит в первом случае. Но почему первый и второй пробеги разные?

Некоторые комментарии к пункту 1:

  • Есть некоторые очевидные вещи, такие как введение моего собственного Переменная окружения, используемая для определения компилятора, который cmake не будет устанавливать самостоятельно. Но в идеале я бы просто смог получить CMake для go, определяющего, например, CXX. Или, возможно, есть функциональность, аналогичная GNU make origin функции , которая может различать guish между переменными, установленными в окружении, и переменными, установленными по умолчанию или в make-файле. 1052 *

  • Если ответ в основном «не делайте этого» (т.е. не заставляйте пользователя определять компилятор), то я не буду считать его конструктивным ответом.

Комментарии к пункту 2:

  • Для меня это выглядит как ошибка в CMake, где он устанавливает CXX при обнаружении компилятора C ++, а затем не сбрасывает эту переменную впоследствии. Но есть ли другой взгляд на это? Или есть документация по этому поводу?

1 Ответ

1 голос
/ 10 марта 2020

Просто проверьте CXX переменную окружения до project() вызов:

if(DEFINED ENV{CXX})
    message("\$CXX = ${CXX}")
else()
    message(SEND_ERROR "\$CXX must be defined by the user to compile this project.")
endif()

project(test)

CXX переменная используется CMake при обнаружении компилятора C ++, и точно project() вызов запускает это обнаружение. Итак, почему вы проверяете переменную после вызова project(), если плохие вещи уже произошли?


Что касается внутренней переменной окружения CXX с помощью CMake, я бы посоветовал не заботиться о что.

Где угодно, установка этой переменной для других целей (не для обнаружения компилятора) будет противоречить использованию этой переменной CMake.

Для выяснения, какой компилятор C ++ используется после project() вызов, проще читать CMAKE_CXX_COMPILER переменная CMake.

...