Зачем добавлять заголовочные файлы в команду ADD_LIBRARY/ADD_EXECUTABLE в CMake

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

В этом шаблоне я перечислил файлы заголовков и исходные файлы в две отдельные переменные, и я не передаю заголовки в команду add_library - только источники. И затем я использую set_target_properties с переменной PUBLIC_HEADER, чтобы предоставить список заголовков.

Пока это работает, но мне кажется, что я делаю вещи излишне сложными. Некоторые люди в Интернете предоставляют заголовочные файлы для команды add_library, а также не используют set_target_properties и т.д.

Короче:

  • следует включить заголовочные файлы в add_library или не следует (как наилучшая практика)? И последствия этого использования.
  • , какова цель, обслуживаемая добавлением заголовков в add_library/add_executable? Похоже, что они работают даже без него (кажется, только декларация и символы). подтвердите пожалуйста понимание.

(Вот шаблон, о котором я говорю:)

cmake_minimum_required(VERSION 3.1.0)

project(lae CXX C) 
set(CMAKE_CXX_STANDARD 14)

include_directories(
  ${CMAKE_CURRENT_SOURCE_DIR}
)

set(SOURCE_FILES
    ...
)

set(HEADER_FILES 
   ...
)

set( PRIVATE_HEADER_FILES
   ...
)

add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ) 

set( REQUIRED_LIBRARIES
   ...
)

target_link_libraries(${PROJECT_NAME} ${REQUIRED_LIBRARIES} )

SET_TARGET_PROPERTIES( 
  ${PROJECT_NAME}  
PROPERTIES 
  FRAMEWORK ON
  SOVERSION 0
  VERSION 0.1.0
  PUBLIC_HEADER "${HEADER_FILES}"
  PRIVATE_HEADER "${PRIVATE_HEADER_FILES}"
  ARCHIVE_OUTPUT_DIRECTORY "lib"
  LIBRARY_OUTPUT_DIRECTORY "lib"
  OUTPUT_NAME ${PROJECT_NAME}
)

Ответ 1

В наших проектах мы используем "простой" способ - add_library с обоими заголовками и источниками.

Если вы добавляете только источники, вы не увидите заголовки в проекте, создаваемом IDE.

Однако при установке мы должны сделать это так, используя две команды install:

install(TARGETS library_name
        LIBRARY DESTINATION lib)

install(FILES ${PUBLIC_HEADERS} 
        DESTINATION include/library_name)

Если вы хотите сделать это как одну команду, вы можете использовать set_target_properties с PUBLIC_HEADER, как вы предложили. Тогда возможен такой тип install:

install(TARGETS library_name
        LIBRARY DESTINATION lib
        PUBLIC_HEADER DESTINATION include/library_name)

Выберите тот, который вам больше всего нравится, и придерживайтесь его.