Как включить библиотеку asio с помощью CMake? - PullRequest
1 голос
/ 09 марта 2020

Я пытаюсь работать над проектом для класса и хочу использовать CMake для создания проекта. Мой текущий проект выглядит как

|-bin
|-CMakeLists.txt
|-include
 |-asio-1.12.2
 |-chat_message.hpp
 |-chat_message.cpp
 |-CMakeLists.txt
|-src
 |-Server.cpp

, хотя моему Серверу. cpp требуется файл asio.hpp, который находится в /include/asio-1.12.2/include. У профессора есть make-файл, который компилирует его с флагами -DASIO_STANDALONE -Wall -O0 -g -std=c++11 -I./include -I./include/asio-1.12.2/include. Мои файлы CMakeLists выглядят следующим образом: Сервер. cpp файл С необходимыми флагами?

1 Ответ

2 голосов
/ 09 марта 2020

Прежде всего, как указал в комментариях *1001* Циварев, команду target_include_directories() нужно разделить на две отдельные команды. Это затем распространит каталоги asio и chat_message в вашу цель Server, которая добавит правильные флаги включения в флаги компилятора.

Примечание: I Рекомендую переключиться с CMAKE_SOURCE_DIR на CMAKE_CURRENT_SOURCE_DIR и соответственно изменить свои пути, чтобы немного упростить свою жизнь, если в будущем вы решите изменить структуру своего проекта, так как обычно сохраняете CMakeLists. TXT-файл находится в том же каталоге, что и источники для создаваемой цели.

Опцию -DASIO_STANDALONE можно добавить с помощью вызова target_compile_definitions():

target_compile_definitions(asio PUBLIC ASIO_STANDALONE)

Обратите внимание, что вам не нужно -D - CMake сгенерирует правильный флаг компилятора для вас. Кроме того, поскольку это требование для цели asio, и оно потребуется всем ее потребителям, к нему следует добавить его, а не потребителей - тогда оно будет распространяться на зависимости по мере необходимости.

В вашем CMakeLists.txt вы установили переменные CPP_STANDARD и CPP_STANDARD_REQUIRED. То, что вам нужно, это CMAKE_CXX_STANDARD и CMAKE_CXX_STANDARD_REQUIRED соответственно.

Это установит флаг для всех целей в вашем проекте.

Существуют различные способы добавить ошибку, оптимизация и флаги отладочных символов, и какой из них вы используете, зависит от вашего варианта использования. Следующее не является исчерпывающим списком.

  • Если вы хотите, чтобы все, кто собирает библиотеку, имели их, независимо от конфигурации сборки (debug / release / et c), вы устанавливаете Переменная CMAKE_CXX_FLAGS в вашем CMakeLists.txt
  • Если вы хотите, чтобы у всех были флаги, но только для определенных типов сборки, установите переменную CMAKE_CXX_FLAGS_<CONFIG>, где <CONFIG> - выбранный тип сборки (DEBUG / RELEASE / MINSIZEREL / RELWITHDEBINFO доступны по умолчанию)
  • Если вы не хотите навязывать флаги всем, перед вызовом CMake вы можете установить переменную окружения CXXFLAGS . Но учтите, что согласно документации это будет неэффективно, если в ваших скриптах CMake установлено CMAKE_CXX_FLAGS.
  • Если вы хотите добавить флаги к одной цели, вы можете вызвать на ней target_compile_options и установите соответствующую опцию видимости, чтобы включить / отключить распространение для потребителей.

Однако, в общем, вам нужно подумать о переносимости при их использовании. Например, G CC может поддерживать определенный флаг, который в Clang может отличаться.

Изменить по адресу this comment

Поскольку библиотека ASIO только для заголовка не поддерживает как и при компиляции с определением компилятора, упомянутым выше, есть два способа его решения:

Снять флаг компилятора ASIO_STANDALONE

Это будет проще всего сделать с вашей точки зрения, но в качестве дополнительного эффекта потребуется, чтобы в вашей системе был установлен Boost, поскольку отсутствие вышеуказанного флага приведет к тому, что препроцессор go будет включен через некоторые включения Boost. Могут быть и другие эффекты, но это первый случай, с которым я столкнулся, прежде чем перейти к решению, приведенному ниже.

Сохраните флаг и используйте библиотеку интерфейса CMake

add_library () может позволить вам добавить цель, которая на самом деле не создает никаких скомпилированных объектов / библиотек / исполняемых файлов, а просто логическую цель CMake, которая может обладать свойствами, такими же, как и любые другие - включая каталоги, библиотеки ссылок и т. Д. c. Поэтому, как минимум, вы можете сделать это:

add_library(asio INTERFACE)
target_compile_options(asio INTERFACE ASIO_STANDALONE)
target_include_directories(asio INTERFACE <dir where asio.hpp lives>)
target_link_libraries(asio INTERFACE <threads>)  # Using ASIO requires you link your final executable/library with your system's threading library (e.g. pthread on linux)

Затем, когда вы свяжете с ним другую цель, например

target_link_libraries(any_lib PRIVATE asio)

any_lib, унаследует все свойства, необходимые для сборки с ASIO.

Решение, которое вы выберете, будет продиктовано вашим вариантом использования, но если вы должны сделать это так же, как ваш профессор, тогда go маршрут библиотеки INTERFACE.

...