Как установить «глобальные» переменные cmake из функции cmake - PullRequest
0 голосов
/ 24 апреля 2018

Я написал функцию, которая мне нравится для загрузки и создания внешнего ресурса.Тем не менее, на практике я сталкиваюсь с проблемой объема работы с функциями cmake, и я хотел бы представить переменные вне функции.Я уже попробовал GLOBAL PROPERTY, PARENT_SCOPE, CACHE STRING и CACHE INTERNAL без успеха.Как я могу обновить «глобальные» переменные в функции ниже?

function(DownloadExternal name source options lib_path)
    string(TOUPPER "${parent}" PARENT)
    MESSAGE(STATUS "${name}")
    MESSAGE(STATUS "     source: ${source}")
    MESSAGE(STATUS "     options: ${options}")
    MESSAGE(STATUS "     lib_path: ${lib_path}")

    set(${name}_prefix      ${EXTERNAL_FOLDER}/${name})
    set(${name}_install_dir ${${name}_prefix})
    list(APPEND ${name}_cmake_args
            ${DEFAULT_CMAKE_FLAGS}
            -DCMAKE_INSTALL_PREFIX=${${name}_prefix}
            -DBUILD_SHARED_LIBS=OFF
            -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
            -DBUILD_SHARED_LIBS=FALSE
            ${options}
            )

    # GLOBAL Variable here is only updated locally
    #  Attempted GLOBAL PROPERTY, CACHE INTERNAL/STRING, PARENT_SCOPE
    list(APPEND EXTRA_LIBS ${${name}_install_dir}/lib/${lib_path})
    externalproject_add(${name}
            PREFIX             ${${name}_prefix}
            GIT_REPOSITORY     ${source}
            GIT_SHALLOW        1
            DOWNLOAD_DIR       ${${name}_prefix}
            UPDATE_COMMAND     git pull
            INSTALL_DIR        ${${name}_install_dir}
            CMAKE_ARGS         ${${name}_cmake_args}
            )
    include_directories(${${name}_prefix}/include)
    link_directories(${${name}_prefix}/lib)
    MESSAGE(STATUS "     prefix: ${${name}_prefix}")
    MESSAGE(STATUS "     cmake: ${${name}_cmake_args}")
    MESSAGE(STATUS "     install: ${${name}_install_dir}")
    MESSAGE(STATUS "     libs: ${EXTRA_LIBS}")
endfunction(DownloadExternal)

Использование (это слишком две строки. Я хочу добавить зависимости внутри функции):

# ----------------------------------------------------------------------------------------------------------------------
#  harfbuzz - A Freetype dependency
# ----------------------------------------------------------------------------------------------------------------------
DownloadExternal(harfbuzz https://github.com/harfbuzz/harfbuzz "-DHB_HAVE_FREETYPE=ON")
ExternalProject_Get_Property(harfbuzz install_dir)
set(harfbuzz_install_dir ${install_dir})

Позже Использование:

add_executable(${CMAKE_PROJECT_NAME} ${${PROJECT_NAME}_SOURCE_FILES})

# TODO: Find a way to make this a list
add_dependencies(freetype harfbuzz)
add_dependencies(${CMAKE_PROJECT_NAME} freetype)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

#  TODO: Find a way to add these in the function
target_link_libraries(${CMAKE_PROJECT_NAME}
        ${harfbuzz_install_dir}/lib/libharfbuzz.a
        )

То, что я хочу сделать, более или менее таково:

# ----------------------------------------------------------------------------------------------------------------------
#  harfbuzz - A Freetype dependency
# ----------------------------------------------------------------------------------------------------------------------
DownloadExternal(harfbuzz https://github.com/harfbuzz/harfbuzz "-DHB_HAVE_FREETYPE=ON" libharfbuzz.a)

...snip...

target_link_libraries(${CMAKE_PROJECT_NAME}
        ${EXTRA_LIBS}
        )

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Вы можете использовать extra_libs параметр входа / выхода DownloadExternal

function(DownloadExternal name source options lib_path extra_list)
        ...
        set(tmpExtra_list ${extra_list} NEW_STUFF_TO_ADD)
        set(${extra_list} ${tmpExtra_list} PARENT_SCOPE) # return value
endfunction()

Плюсы:

  • Известная концепция во многих языках программирования
  • Нет магии, откуда берется переменная
  • Пользователь вашей функции может определить одно имя для переменной

контрас:

  • Подпись вашей функции должна быть изменена
0 голосов
/ 24 апреля 2018

Я считаю, что это работает.

Глобальное свойство должно быть определено в верхней части cmake ...

DEFINE_PROPERTY(GLOBAL PROPERTY EXTRA_LIBS
        BRIEF_DOCS "Contains linkable libraries"
        FULL_DOCS "Contains paths to libraries for linking")

Тогда внутри функции мы должны установить локальную переменную всодержимое глобального свойства.Кроме того, обновите локальную переменную и затем добавьте ее обратно в глобальное свойство.

function(DownloadExternal name source options lib_path)
    string(TOUPPER "${parent}" PARENT)
    MESSAGE(STATUS "---------------------------------------------------------------------------")
    MESSAGE(STATUS "${name}")
    MESSAGE(STATUS "     source: ${source}")
    MESSAGE(STATUS "     options: ${options}")
    MESSAGE(STATUS "     lib_path: ${lib_path}")
    GET_PROPERTY(extra_libs GLOBAL PROPERTY EXTRA_LIBS)
    set(${name}_prefix      ${EXTERNAL_FOLDER}/${name})
    set(${name}_install_dir ${${name}_prefix})
    list(APPEND ${name}_cmake_args
            ${DEFAULT_CMAKE_FLAGS}
            -DCMAKE_INSTALL_PREFIX=${${name}_prefix}
            -DBUILD_SHARED_LIBS=OFF
            -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
            -DBUILD_SHARED_LIBS=FALSE
            ${options}
            )
    list(APPEND extra_libs ${${name}_install_dir}/lib/${lib_path})
    SET_PROPERTY(GLOBAL PROPERTY EXTRA_LIBS ${extra_libs})
    externalproject_add(${name}
            PREFIX             ${${name}_prefix}
            GIT_REPOSITORY     ${source}
            GIT_SHALLOW        1
            DOWNLOAD_DIR       ${${name}_prefix}
            UPDATE_COMMAND     git pull
            INSTALL_DIR        ${${name}_install_dir}
            CMAKE_ARGS         ${${name}_cmake_args}
            )
    include_directories(${${name}_prefix}/include)
    link_directories(${${name}_prefix}/lib)
    MESSAGE(STATUS "     prefix: ${${name}_prefix}")
    MESSAGE(STATUS "     cmake: ${${name}_cmake_args}")
    MESSAGE(STATUS "     install: ${${name}_install_dir}")
    MESSAGE(STATUS "     libs: ${extra_libs}")
endfunction(DownloadExternal)

Наконец, чтобы использовать свойство позже, мы также должны получить его снова.

GET_PROPERTY(extra_libs GLOBAL PROPERTY EXTRA_LIBS)
target_link_libraries(${CMAKE_PROJECT_NAME}
        ${BZIP2_LIBRARIES}
        ${OPENGL_LIBRARIES}
        ${extra_libs}
        )
...