Function 如何设置;“全球”;cmake函数中的cmake变量
我写了一个函数,我喜欢下载和构建外部资源。然而,实际上,我遇到了cmake函数的作用域问题,我想公开函数之外的变量。我已经尝试了全局属性、父范围、缓存字符串和缓存内部,但没有成功。如何更新下面函数中的“全局”变量Function 如何设置;“全球”;cmake函数中的cmake变量,function,variables,scope,cmake,Function,Variables,Scope,Cmake,我写了一个函数,我喜欢下载和构建外部资源。然而,实际上,我遇到了cmake函数的作用域问题,我想公开函数之外的变量。我已经尝试了全局属性、父范围、缓存字符串和缓存内部,但没有成功。如何更新下面函数中的“全局”变量 function(DownloadExternal name source options lib_path) string(TOUPPER "${parent}" PARENT) MESSAGE(STATUS "${name}") MESSAGE(STATUS
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)
用法(这太长了两行。我想在函数中添加依赖项):
以后的用法:
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}
)
我相信这是可行的
必须在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}
)
您可以使用
extra_libs
的输入/输出参数downloadeexternal
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()
优点:
- 许多编程语言中的已知概念
- 变量来自哪里没有魔力
- 函数的用户可以为变量定义一个名称
- 必须修改您的函数签名
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()