Объединение нескольких целей библиотеки cmake в одну цель сбой при запуске под действием GitHub

#github #cmake

#github #cmake

Вопрос:

Я пытаюсь настроить непрерывный рабочий процесс интеграции GitHub с использованием современной системы сборки cmake. В этой системе сборки у меня есть две внешние библиотеки, которые мне нужно найти, версии C и Fortran. Поскольку эти библиотеки не встроены в FindLIBRARY, мне пришлось создать свою собственную. Я также хотел настроить его так, чтобы обе библиотеки могли быть связаны как одна цель.

 find_path (LIBRARY_INCLUDE_DIR
           NAMES library.h)
mark_as_advanced (LIBRARY_INCLUDE_DIR)

find_library(LIBRARY_C_LIBRARY
             NAMES c_version)
mark_as_advanced (LIBRARY_C_LIBRARY)
find_library(LIBRARY_Fortran_LIBRARY
             NAMES fortran_version)
mark_as_advanced (LIBRARY_Fortran_LIBRARY)

include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (LIBRARY
                                   REQUIRED_VARS LIBRARY_C_LIBRARY LIBRARY_Fortran_LIBRARY     LIBRARY_INCLUDE_DIR

if (LIBRARY_FOUND)
    set (LIBRARY_INCLUDE_DIRS ${LIBRARY_INCLUDE_DIR})
    set (LIBRARY_LIBRARIES "${LIBRARY_C_LIBRARY} ${LIBRARY_Fortran_LIBRARY}")

    if (NOT TARGET LIBRARY::LIBRARY_C)
        add_library (LIBRARY::LIBRARY_C UNKNOWN IMPORTED)
        set_target_properties (LIBRARY::LIBRARY_C PROPERTIES
                               IMPORTED_LOCATION ${LIBRARY_C_LIBRARY}
                               INTERFACE_INCLUDE_DIRECTORIES ${LIBRARY_INCLUDE_DIR})
    endif ()
    if (NOT TARGET LIBRARY::LIBRARY_Fortran)
        add_library (LIBRARY::LIBRARY_Fortran UNKNOWN IMPORTED)
        set_target_properties (LIBRARY::LIBRARY_Fortran PROPERTIES
                               IMPORTED_LOCATION ${LIBRARY_Fortran_LIBRARY}
                               INTERFACE_INCLUDE_DIRECTORIES ${LIBRARY_INCLUDE_DIR})
    endif ()

    if (NOT TARGET LIBRARY::LIBRARY)
        add_library (LIBRARY::LIBRARY INTERFACE IMPORTED)
        target_link_libraries (LIBRARY::LIBRARY INTERFACE LIBRARY::LIBRARY_C LIBRARY::LIBRARY_Fortran)
    endif ()
endif ()
  

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

 cmake_minimum_required (VERSION 3.14)

project (my_project C Fortran)

set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package (LIBRARY MODULE REQUIRED)

add_library(my_library STATIC)

... # Add target sources here.

if (LIBRARY_FOUND)
    target_link_libraries (my_library INTERFACE LIBRARY::LIBRARY)
endif ()
  

Затем я использую my_library где-нибудь исполняемый файл.

 add_executable (my_program)
target_link_libraries (my_program my_library)
  

Все работает нормально, когда я запускаю его на своем локальном компьютере разработчика (macOS 10.14.6). my_program извлекает все определения компиляции, включая каталоги и свойства флага компилятора, которые установлены для связанных целевых объектов. Однако это не удается, когда я пытаюсь запустить его как действие GitHub (последняя версия ubuntu). Когда я создаю с make VERBOSE=1 помощью, я вижу, что LIBRARY_INCLUDE_DIR свойство отсутствует. На обеих машинах установлена одна и та же версия cmake.

Комментарии:

1. «Я вижу, что свойство LIBRARY_INCLUDE_DIR отсутствует». — Итак, это первая строка в вашем скрипте, которая была сброшена. Как эта проблема связана с «расчесыванием целей библиотеки CMake», как написано в названии?

2. find_path определяет LIBRARY_INCLUDE_DIR переменную.

3. Да, первая строка, find_path , определяет LIBRARY_INCLUDE_DIR переменную. Если файл заголовка не найден, то переменной присваивается значение -NOTFOUND . По «Я вижу, что LIBRARY_INCLUDE_DIR свойство отсутствует». вы имеете в виду последний случай, не так ли?

4. Он отлично находит заголовок.

5. О, тогда я неправильно понял ваше заявление о проблеме — «Я вижу, что свойство LIBRARY_INCLUDE_DIR отсутствует». Не могли бы вы уточнить это? Означает ли это, что значение LIBRARY_INCLUDE_DIR не передается компилятору? Если да, пробовали ли вы (для целей отладки), работает ли связывание с отдельными целями: target_link_libraries (my_library INTERFACE LIBRARY::LIBRARY_C LIBRARY::LIBRARY_FORTRAN) ?

Ответ №1:

Оказалось, что исправление должно было измениться

 if (LIBRARY_FOUND)
    target_link_libraries (my_library INTERFACE LIBRARY::LIBRARY)
endif ()
  

Для

 if (LIBRARY_FOUND)
    target_link_libraries (my_library PUBLIC LIBRARY::LIBRARY)
endif ()
  

Связывание его как INTERFACE , означало, что вещи, которые будут ссылаться на my_library , будут видеть каталог включения, но my_library источники этого не сделали.