Cmake: target_compile_definitions с помощью find_package

У меня есть пакет libtorch, который зависит от библиотек, использующих ключевое слово slots для некоторых функций (например, в Aten). А пока проект, который я использую, основан на Qt, в котором slots используется как специальное ключевое слово (макрос), которое затем мешает torchlib.

Решение избежать такого вмешательства состоит в том, чтобы добавить определение QT_NO_KEYWORDS при импорте внешней библиотеки, которая конфликтует с Qt: Включение no_keyword (опция Qt) в файле cmake для работы с boost::signals

Затем это нужно сделать только для кода, который зависит от libtorch, а не от остального, поэтому я попробовал несколько способов добавить его, например CMake Добавить и удалить определение макроса для компиляции общей библиотеки/исполняемого файла и Добавить целевые свойства в существующую импортированную библиотеку в CMake, но я не могу заставить ее Работа.

target_compile_definitions кажется доступным после cmake 3.11 для ИМПОРТНЫХ целей (по терминологии cmake).

Итак, почему следующий экстракт cmakelist не работает? (в этом случае обычный код слотов QT не распознается должным образом как макрос):

find_package (Torch REQUIRED PATHS ${Torch_DIR})
add_executable( ${PROJECT_NAME} ${header_files} ${source_files} ${hpp_files} ${moc_list} ${generated_ui_files} ${generated_qrc_files} )
target_link_libraries(${PROJECT_NAME} ${Qt_LINK_LIBRARIES})
#add_definitions(-DQT_NO_KEYWORDS)
target_link_libraries(${PROJECT_NAME} ${TORCH_LIBRARIES})
#remove_definitions(-DQT_NO_KEYWORDS)
target_compile_definitions(torch INTERFACE QT_NO_KEYWORDS)

person Emile D.    schedule 06.07.2021    source источник


Ответы (1)


Возможные решения

Вариант 1:

Используйте QT_NO_KEYWORDS и замените slots и другие ключевые слова их эквивалентными макросами в верхнем регистре, например. Q_SLOTS.

Вариант 2:

Не используйте QT_NO_KEYWORDS и не оборачивайте части кода C++ конфликтующими ключевыми словами, например:

#undef slots
#include <torch/torch.h>
#define slots Q_SLOTS

Пояснения

Ключевое слово INTERFACE в target_compile_definitions() сообщает CMake, что все цели, зависящие от библиотеки torch, также нуждаются в определении макроса QT_NO_KEYWORDS. Вот почему все исходники вашего исполняемого файла будут скомпилированы с -DAT_NO_KEYWORDS, а ключевое слово slots не будет определено.

Я полагаю, вы пытались решить проблему с закомментированными вызовами add_definitions()/remove_definitions(). Несколько причин, по которым они не работают должным образом:

  • Они влияют только на компиляцию, а не на компоновку. Размещение их вокруг target_link_libraries() не дает никакого эффекта.
  • Они манипулируют флагами компиляции всех целей, созданных в текущей области (текущий файл CMakeLists.txt), независимо от того, были ли они созданы до или после вызова команды, см. документы. Это означает, что вызов add_definitions(), а затем remove_definitions() с одними и теми же аргументами приведет к тому, что никакие флаги не будут добавлены вообще, независимо от того, в какой точке вашего CMakeLists.txt вы их вызываете.

Вы также должны отметить, что команды, работающие на уровне каталога (add_*/remove_*), считаются CMake старого стиля. Современный CMake работает только на целевом уровне (target_* команд). Еще несколько предложений Modern CMake:

  • Используйте target_sources() вместо таких переменных, как header_files, source_files и т. д. чтобы добавить источники к вашим целям.
  • Всегда используйте target_link_libraries() с ключевыми словами PRIVATE, PUBLIC или INTERFACE. Выдержка из книги Крейга Скотта Professional CMake:
    #P8#
person peter_w    schedule 09.07.2021