C ++ CMake Директивы компиляции против? - PullRequest
2 голосов
/ 31 января 2020

В настоящее время я строю большие проекты, содержащие несколько подпроектов (из подпроектов (из ...)). Каждый подпроект может иметь директивы компилятора. Если директива компилятора находится на самом низком уровне подпроектов, директивы компилятора затем передаются на каждый уровень выше подпроекта на самом низком уровне, что приводит к большому количеству проектов в конце.

Первый вопрос: это хорошая практика? Какие могут быть альтернативы?

Второй вопрос: Было бы хорошей практикой передавать директиву компилятора на верхнем уровне (т.е. MyApp)? У приложения будут члены, переданные в конструктор подпроектов с параметрами опции ...

Например, у меня есть приложение (MyApp) с подпроектом (сеть). Самый нижний подпроект (сеть) содержит все сетевые модули и методы с директивой компилятора IPV6 . В конце у меня есть четыре проекта:

  • MyApp с сетью
  • MyApp_IPV6 с сетью_IPV6

Теперь я позволю себе представить несколько подпроектов на разных уровнях и различные директивы компилятора ...

edit: Под директивами компилятора я подразумеваю определения компиляции как:

#ifdef IPV6
// do stuff
#endif

1 Ответ

3 голосов
/ 31 января 2020

В CMake вы бы сделали это, используя свойства цели:

add_executable(MyApp ...)
add_executable(MyApp_IPV6 ...)

add_subdirectory(network)

# consumes the public interface of network
target_link_libraries(MyApp PRIVATE network)

# consumes the public interface of network_IPV6
target_link_libraries(MyApp_IPV6 PRIVATE network_IPV6)

Затем в файле CMake внутри network/ добавьте вашу цель и ее определение компиляции:

add_library(network STATIC files...)
add_library(network_IPV6 STATIC files...)

# add IPV6 into its interface
target_compile_definitions(network_IPV6 PUBLIC IPV6)

Потому что цель network_IPV6 устанавливает определение как IPV6, у любого, кто ссылается на него, тоже будет это определение.


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

Это будет работать так:

option(MYAPP_USE_IPV6 "Compile MyApp with ipv6 support", OFF)
add_subdirectory(network)

# consumes the public interface of network
target_link_libraries(MyApp PRIVATE network)

Затем внутри сетевого каталога:

add_library(network STATIC files...)

if (MYAPP_USE_IPV6)
    # add IPV6 into its interface
    target_compile_definitions(network_IPV6 PUBLIC IPV6)
endif()

Затем вы настраиваете свое приложение при необходимости или настройте оба профиля:

mkdir build
mkdir build-ipv6

cd build
cmake ..

cd ../build-ipv6
cmake .. -DMYAPP_USE_IPV6=ON
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...