Как сделать target_link_libraries в CMake без реальных ссылок? - PullRequest
2 голосов
/ 13 февраля 2020

Теперь я знаю, как звучит вопрос ... однако, target_link_libraries делает больше, чем просто ссылки. И я хочу это «больше», но не связывание. Как это сделать?

Моя текущая настройка выглядит (в упрощенном виде) следующим образом:

CMake targets and their relations

«Сторонняя организация» цель - PkgConfig созданная цель. Остальное мое.

Однако эта настройка создает проблему в тестах. В «Приложениях УЦ» я не хочу использовать библиотеку «Сторонних производителей». Я хочу использовать его заглушку. Чтобы поместить это в изображение, я хотел бы иметь следующее:

Desired CMake setup

Пунктирные линии - это «что-то» - это может быть цель зависимости (чтобы не повторять одну и ту же информацию, например, включающие пути), однако, я считаю это подробностью реализации, пока она работает.

Если бы я контролировал цели «третьей стороны», я бы просто сделал им нравится это. Но не я. Я получаю .pc файлов, и у меня есть цель, созданная PkgConfig . В то время как созданная цель - это единственная цель, имеющая все это.

Пока что я решил ее, создав пользовательскую функцию target_nonlink_libraries, которая распространяет следующие свойства цели:

(Обратите внимание, что это включает не все INTERFACE_... properties.)

Код выглядит следующим образом:

function(target_nonlink_libraries TARGET_NAME SCOPE SOURCE_TARGET)
    foreach(source_target IN ITEMS ${SOURCE_TARGET} ${ARGN})
        get_target_property(interface_compile_definitions ${source_target} INTERFACE_COMPILE_DEFINITIONS)
        if(interface_compile_definitions)
            target_compile_definitions(${TARGET_NAME}
                ${SCOPE}
                    ${interface_compile_definitions}
            )
        endif()

        get_target_property(interface_compile_features ${source_target} INTERFACE_COMPILE_FEATURES)
        if(interface_compile_features)
            target_compile_definitions(${TARGET_NAME}
                ${SCOPE}
                    ${interface_compile_features}
            )
        endif()

        get_target_property(interface_compile_options ${source_target} INTERFACE_COMPILE_OPTIONS)
        if(interface_compile_options)
            target_compile_options(${TARGET_NAME}
                ${SCOPE}
                    ${interface_compile_options}
            )
        endif()

        get_target_property(interface_include_directories ${source_target} INTERFACE_INCLUDE_DIRECTORIES)
        if(interface_include_directories)
            target_include_directories(${TARGET_NAME}
                ${SCOPE}
                    ${interface_include_directories}
            )
        endif()

        get_target_property(interface_system_include_directories ${source_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
        if(interface_system_include_directories)
            target_include_directories(${TARGET_NAME} SYSTEM
                ${SCOPE}
                    ${interface_system_include_directories}
            )
        endif()
    endforeach()
endfunction()

и позже используется так:

target_nonlink_libraries(ApplicationCommon
    INTERFACE
        PkgConfig::Library
)
target_link_libraries(Application
    PRIVATE
        PkgConfig::Library
)

Однако проблема в том, что я ' я не уверен, что я копирую все свойства (которые меня интересуют) и делаю это правильно.

Как решить эту проблему в CMake? Существует ли какая-либо встроенная функция для ссылки на цели, явно пропускающая фактическую ссылку?

...