Добавление флагов компилятора в CMakeLists.txt - PullRequest
0 голосов
/ 26 мая 2018

Я хочу использовать новейшую версию библиотеки Boost и иметь следующее содержимое файла CMakeLists.txt:

cmake_minimum_required (VERSION 3.0)
project (foo)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DBOOST_ERROR_CODE_HEADER_ONLY -lpthread")
# set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread")

add_executable (first first.cpp)

При этом я получаю следующую ошибку компоновщика:

неопределенная ссылка на `pthread_detach

Однако, если я скомпилирую свой код без использования cmake, с помощью следующей команды:

g++ foo.cpp -std=c++11 -DBOOST_ERROR_CODE_HEADER_ONLY -lpthread

Работает нормально.

Вопрос в том, как заставить его работать с помощью cmake.Почему это не работает, когда я задаю флаги компилятора через настройку CMAKE_CXX_FLAGS?Я подумал, что вместо этого мне может потребоваться указать CMAKE_EXE_LINKER_FLAGS, но это совсем не поможет.

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

В общем случае следует указывать библиотеки, используя target_link_libraries вместо переопределения флагов компоновщика напрямую.


В этом случае вы можете сделать это по-другому:

add_executable (first first.cpp)

find_package(Threads REQUIRED)
target_link_libraries(first PRIVATE Threads::Threads)

Threads::Threads выше означает многопоточную библиотеку для вашей системы.Это дает преимущество кроссплатформенности - когда вы хотите скомпилировать свой проект, например, в Windows, компоновщик не будет жаловаться на неизвестную библиотеку pthread.

По той же причине установка версии C ++ способом @Angew в своем ответе предпочитает - он просто работает, без необходимости вручную настраивать флаги для каждого компилятора.

0 голосов
/ 26 мая 2018

CMake имеет встроенную поддержку всех вещей, которые вы пытаетесь решить с помощью явной спецификации флага, поэтому вы должны использовать это вместо:

cmake_minimum_required (VERSION 3.0)
project (foo)

add_executable (first first.cpp)
target_compile_options (first PRIVATE -std=c++11)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)

Если вы можете увеличить минимальные требования к версии CMakeдо версии 3.1, вы можете также заменить жестко закодированный флаг std на собственный CMake:

cmake_minimum_required (VERSION 3.1)
project (foo)

add_executable (first first.cpp)
set_target_properties (first PROPERTIES
  CXX_STANDARD 11
  CXX_STANDARD_REQUIRED TRUE
  CXX_EXTENSIONS FALSE
)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)

Преимущество заключается в том, что не все компиляторы выражают «использовать C ++ 11 без расширений» одинаково, иCMake переведет требование в правильные для вас флаги.

Если вам понадобится одна и та же установка C ++ 11 для многих исполняемых файлов, вы можете вместо этого установить переменные CMake, которые предварительно заполняют свойства.Обратите внимание, что переменные должны быть установлены до того, как будут созданы исполняемые файлы:

set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD_REQUIRED TRUE)
set (CMAKE_CXX_EXTENSIONS FALSE)

add_executable (first first.cpp)
target_compile_definitions (first PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (first pthread)

add_executable (second second.cpp)
target_compile_definitions (second PRIVATE BOOST_ERROR_CODE_HEADER_ONLY)
target_link_libraries (second pthread)

# ... and so on
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...