Создать .lib библиотеки только для заголовков, которая зависит от внешних ресурсов - PullRequest
0 голосов
/ 03 декабря 2018

РЕДАКТИРОВАТЬ: Я прочитал и понял, что первоначальная проблема была вызвана тем, что только у заголовка сканирования не было файлов cpp и, следовательно, не был создан файл lib.Отредактировал вопрос, чтобы отразить это дополнительное понимание:

Структура моего текущего проекта и соответствующее содержимое CMakeLists:

leveling
├── CMakeLists.txt: add_subdirectory(deps) 
└── deps
    ├── CMakeLists.txt: add_subdirectory(scanning-header-only)
    └── scanning
        ├── CMakeLists.txt: add_subdirectory(deps)
        │                   add_library(scanning-header-only file.h)
        │                   target_include_directories(scanning-header-only PUBLIC ${CMAKE_CURRENT_LIST_DIR}/deps/tinyxml2)
        │                   target_link_libraries(scanning-header-only PUBLIC tinyxml2)
        └── deps
            ├── CMakeLists.txt: add_subdirectory(tinyxml2)
            └── tinyxml2

Но файл библиотеки только для заголовка сканирования не создается, и поэтомукорневой проект не может target_link_libraries (выравнивание только для заголовка scan) и должен был target_include_directories(leveling ${CMAKE_CURRENT_LIST_DIR}/deps/scanning-header-only/deps/tinyxml2)

Возможно ли target_link_library библиотека только для заголовка, которая зависит от внешних ресурсов?

Я вижу, что библиотека только для заголовков без зависимости от внешних ресурсов может быть add_library(.. INTERFACE), но мне не удается сделать это с зависимостью от tinyxml2

Грязный обходной путь - добавление и очистка файла cpp только для scan-header-header, так что создается файл lib, но есть ли правильный способ сделать это?



Вот минимальный пример v1:https://www.dropbox.com/s/r1lbajz3xoat1bg/leveling-header-only-test%20v1.zip?dl=0

выравнивание CMakeLists.txt: cmake_minimum_required (VERSION 3.8)

set(LEVELING_NAME leveling)

project(${LEVELING_NAME})

#
# To put tinyxml.dll next to the executable, to workaround having to make tinyxml2.dll reachable in PATH
#
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

math(EXPR platform_bits "${CMAKE_SIZEOF_VOID_P} * 8")
set(platform_dir bin/${CMAKE_SYSTEM_NAME}-${platform_bits})

foreach(config DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
    foreach(var
            CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config}
            CMAKE_LIBRARY_OUTPUT_DIRECTORY_${config}
            CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config}
            )
        set(${var} "${CMAKE_BINARY_DIR}/${platform_dir}/${config}")
        string(TOLOWER "${${var}}" ${var})
    endforeach()
endforeach()
#
# ----------------------------------------------------------------------
#

add_subdirectory(deps)

add_executable(${LEVELING_NAME} main.cpp)

target_include_directories(${LEVELING_NAME} PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}/deps/scanning 
)

target_link_libraries(${LEVELING_NAME} 
    xml-reading
)

set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${LEVELING_NAME}) # Set Startup Project in VS. Implemented in CMake v3.6
set_target_properties(${LEVELING_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") # Set Working Directory of project in VS. Implemented in CMake v3.8

сканирование CMakeLists.txt

cmake_minimum_required(VERSION 3.8)

set(XML_NAME xml-reading)

project(${XML_NAME})

#
# To put tinyxml.dll next to the executable, to workaround having to make tinyxml2.dll reachable in PATH
#
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

math(EXPR platform_bits "${CMAKE_SIZEOF_VOID_P} * 8")
set(platform_dir bin/${CMAKE_SYSTEM_NAME}-${platform_bits})

foreach(config DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
    foreach(var
            CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config}
            CMAKE_LIBRARY_OUTPUT_DIRECTORY_${config}
            CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config}
            )
        set(${var} "${CMAKE_BINARY_DIR}/${platform_dir}/${config}")
        string(TOLOWER "${${var}}" ${var})
    endforeach()
endforeach()
#
# ----------------------------------------------------------------------
#

add_subdirectory(deps)

add_library(${XML_NAME} INTERFACE CamerasXML.h)
target_include_directories(${XML_NAME} INTERFACE
    ${CMAKE_CURRENT_LIST_DIR}/deps/tinyxml2
)
target_link_libraries(${XML_NAME} 
    INTERFACE tinyxml2
)

, что дает

CMake Error at deps/scanning/CMakeLists.txt:33 (add_library): 
  add_library INTERFACE library requires no source arguments. 

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Простой add_library(${XML_NAME} INTERFACE) (без указания каких-либо исходных файлов), в то время как наличие target_include_directories(${XML_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}/deps/tinyxml2) и target_link_libraries(${XML_NAME} INTERFACE tinyxml2) сделает свое дело.

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

0 голосов
/ 04 декабря 2018

A .lib - это когда вы создаете STATIC (.lib) или SHARED (.lib и .dll) библиотеку в Windows.Вам нужна библиотека INTERFACE, и она не генерирует файлы.http://mariobadr.com/creating-a-header-only-library-with-cmake.html имеет пример.Затем вы можете использовать следующие команды, перечисленные здесь, https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries, для заполнения интерфейса.Обратите внимание, что он использует INTERFACE, а не PUBLIC.

target_link_libraries(INTERFACE),
target_link_options(INTERFACE),
target_include_directories(INTERFACE),
target_compile_options(INTERFACE),
target_compile_definitions(INTERFACE), and
target_sources(INTERFACE),

На самом деле я никогда не использовал это, но я предполагаю, что он работает так, как задокументировано.

...