简述
- 指定库的路径
- 链接时使用绝对路径方式
find_library()
:查找/指定所需的库(推荐).link_directories()
:指定第三方库所在路径(只有在生成target之前调用才会有效, 即需要放在ADD_EXECUTABLE()之前调用)link_libraries()
:添加需要链接的库文件路径,注意这里是全路径,(不推荐)- 指定所需头文件的路径
include_directories()
:添加头文件路径到编译器的头文件搜索路径下,多个路径以空格分隔.- 其他
find_path()
:和find_library()类似,find_path()可以用来找任何文件.find_package()
:引入外部依赖包.- 链接目标
target_link_libraries
:指定目标(exe或者so文件)需要包含的库target_include_directories
:指定目标(exe或者so文件)需要包含的头文件路径
指定第三方库所在路径,比如,你的动态库在/home/myproject/libs这个路径下,则通过命令:LINK_DIRECTORIES(/home/myproject/libs),把该路径添加到第三方库搜索路径中,这样就可以使用相对路径了,使用TARGET_LINK_LIBRARIES的时候,只需要给出动态链接库的名字就行了。
link_directories([AFTER|BEFORE] directory1 [directory2 ...])
# Adds the paths in which the linker should search for libraries.
# Relative paths given to this command are interpreted as relative to the current source directory.
# The command will apply only to targets created after it is called.
添加链接器将在其中查找库的目录
link_libraries([item1 [item2 [...]]][[debug|optimized|general] - ] ...)
# Specify libraries or flags to use when linking any targets created later in the current directory or below by commands such as add_executable() or add_library().
# See the target_link_libraries() command for meaning of arguments.
此命令用于查找库。创建一个缓存条目,或者一个普通变量,如果指定了 NO_CACHE ,由 命名来存储这个命令的结果。如果找到库,结果将存储在变量中,除非清除变量,否则不会重复搜索。如果什么也没找到,结果将是 -NOTFOUND 。
通常指定NAMES
和HINTS
即可.
#A short-hand signature is:
find_library ( name1 [path1 path2 ...])
#The general signature is:
find_library (name | NAMES name1 [name2 ...] [NAMES_PER_DIR][HINTS [path | ENV var]... ][PATHS [path | ENV var]... ][REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)][PATH_SUFFIXES suffix1 [suffix2 ...]][VALIDATOR function][DOC "cache documentation string"][NO_CACHE][REQUIRED][NO_DEFAULT_PATH][NO_PACKAGE_ROOT_PATH][NO_CMAKE_PATH][NO_CMAKE_ENVIRONMENT_PATH][NO_SYSTEM_ENVIRONMENT_PATH][NO_CMAKE_SYSTEM_PATH][NO_CMAKE_INSTALL_PREFIX][CMAKE_FIND_ROOT_PATH_BOTH |ONLY_CMAKE_FIND_ROOT_PATH |NO_CMAKE_FIND_ROOT_PATH])
NAMES
为库指定一个或多个可能的名称。
当使用这个来指定有版本后缀和没有版本后缀的名称时,我们建议先指定没有版本的名称,这样就可以在发行版提供的软件包之前找到本地构建的软件包。
HINTS, PATHS
除了默认位置,还指定要搜索的目录。该 ENV var
子选项读取系统环境变量的路径。
在 3.24 版更改: 在 Windows
平台上,可以使用专用语法将注册表查询作为目录的一部分。在所有其他平台上,此类规范将被忽略。
REGISTRY_VIEW
3.24版的新内容。
指定必须查询哪些注册表视图。此选项仅在 Windows
平台上有意义,在其他平台上将被忽略。如果未指定,则在 CMP0134
策略为 NEW
时使用 TARGET
视图。策略为 OLD
时的默认视图,请参阅 CMP0134
。 CMP0134
NEW
CMP0134
OLD
64
查询 64 位注册表。在 32 位 Windows 上,它始终返回字符串 /REGISTRY-NOTFOUND
。
32
查询32位注册表。
64_32
查询两个视图( 64
和 32
)并为每个视图生成路径。
32_64
查询两个视图( 32
和 64
)并为每个视图生成路径。
HOST
查询与主机架构匹配的注册表: 64
位Windows为64,32位Windows为 32
。
TARGET
查询与 CMAKE_SIZEOF_VOID_P
变量指定的体系结构匹配的注册表。如果未定义,则回退到 HOST
视图。
BOTH
查询两个视图( 32
和 64
)。顺序取决于以下规则: 如果定义了 CMAKE_SIZEOF_VOID_P
变量,请根据该变量的内容使用以下视图:
8
: 64_32
4
: 32_64
如果没有定义 CMAKE_SIZEOF_VOID_P
变量,依赖主机的架构:
64_32
32
PATH_SUFFIXES
在每个目录位置下面指定额外的子目录进行检查,否则视为无效。
DOC
指定 缓存条目的文档字符串。
NO_CACHE
3.21版中的新内容。
搜索的结果将被存储在一个普通的变量中,而不是缓存条目。
Note
如果该变量在调用前已经被设置(作为普通变量或缓存变量),那么搜索将不会发生。
Warning
这个选项应该谨慎使用,因为它可能大大增加重复配置步骤的成本。
REQUIRED
3.18版本中的新功能。
如果没有找到,则停止处理,并发出错误信息,否则在下一次用相同的变量调用find_library时,将再次尝试搜索。
如果指定了 NO_DEFAULT_PATH
,则不会将其他路径添加到搜索中。如果未指定 NO_DEFAULT_PATH
,则搜索过程如下:
3.12版中的新增功能:如果从查找模块中调用或由对 find_package(
的调用加载的任何其他脚本中调用,则搜索前缀对于要查找的当前包是唯一的。具体来说,请查看
CMake变量和
环境变量。包的根变量作为堆栈维护,因此,如果从嵌套查找模块或配置包中调用,则将在当前模块或包的路径之后搜索父级查找模块或配置包的根路径。换句话说,搜索顺序为
, ENV{
,
, ENV{
等等。如果传递了 NO_PACKAGE_ROOT_PATH
或将 CMAKE_FIND_USE_PACKAGE_ROOT_PATH
设置为 FALSE
,则可以跳过此操作。请参阅策略 CMP0074
。
/lib/
(如果已设置 CMAKE_LIBRARY_ARCHITECTURE
),并且 /lib
_ROOT
CMake变量和 _ROOT
环境变量中的每个
的 / lib(如果已从由加载的find模块中调用) find_package()
在特定于 cmake 的缓存变量中指定的搜索路径。这些旨在通过 -DVAR=value
在命令行上使用。这些值被解释为分号分隔的列表。 NO_CMAKE_PATH
或将 CMAKE_FIND_USE_CMAKE_PATH
设置为 FALSE
,则可以跳过此操作。
/lib/
如果 CMAKE_LIBRARY_ARCHITECTURE
被设置,并 /lib
用于每个
在 CMAKE_PREFIX_PATH
CMAKE_LIBRARY_PATH
CMAKE_FRAMEWORK_PATH
在特定于cmake的环境变量中指定的搜索路径。这些意在用户的外壳配置进行设置,并因此使用主机的本地路径分隔( ;
在Windows和 :
在UNIX上)。这可如果跳过 NO_CMAKE_ENVIRONMENT_PATH
传递或通过设置 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH
到 FALSE
。
/lib/
如果 CMAKE_LIBRARY_ARCHITECTURE
被设置,并 /lib
用于每个
在 CMAKE_PREFIX_PATH
CMAKE_LIBRARY_PATH
CMAKE_FRAMEWORK_PATH
搜索“ HINTS
选项指定的路径。这些应该是系统自省计算的路径,例如已经找到的另一个项目的位置所提供的提示。硬编码的猜测应使用 PATHS
选项指定。
搜索标准系统环境变量。这可如果跳过 NO_SYSTEM_ENVIRONMENT_PATH
传递或通过设置 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH
到 FALSE
。
LIB
和 PATH
中的目录。/lib/
如果 CMAKE_LIBRARY_ARCHITECTURE
是集,而 /lib
用于每个 /[s]bin
在 PATH
,和 /lib
用于其他条目 PATH
。搜索当前系统的 Platform 文件中定义的 cmake 变量。 NO_CMAKE_INSTALL_PREFIX
或将 CMAKE_FIND_USE_INSTALL_PREFIX
设置为 FALSE
,则可以跳过 CMAKE_INSTALL_PREFIX
和 CMAKE_STAGING_PREFIX
的搜索。 NO_CMAKE_SYSTEM_PATH
或将 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
设置为 FALSE
,则可以跳过所有这些位置。 NO_CMAKE_INSTALL_PREFIX
CMAKE_FIND_USE_INSTALL_PREFIX
FALSE
NO_CMAKE_SYSTEM_PATH
CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
FALSE
/lib/
如果 CMAKE_LIBRARY_ARCHITECTURE
被设置,并 /lib
用于每个
在 CMAKE_SYSTEM_PREFIX_PATH
CMAKE_SYSTEM_LIBRARY_PATH
CMAKE_SYSTEM_FRAMEWORK_PATH
这些变量包含的平台路径是通常包含已安装软件的位置。对于基于UNIX的平台,示例为 /usr/local
。
查询两个视图( 32
和 64
)。顺序取决于以下规则: 如果定义了 CMAKE_SIZEOF_VOID_P
变量,请根据该变量的内容使用以下视图:
8
: 64_32
4
: 32_64
如果没有定义 CMAKE_SIZEOF_VOID_P
变量,依赖主机的架构:
64_32
32
搜索PATHS选项或命令的简写版中指定的路径。这些通常是硬编码的猜测.
它相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用(这里特指c++。c和Java中用法类似)。
此属性包含一个以分号分隔的路径列表,并将在此源文件构建时添加到包含目录列表中。由于技术限制,这些目录将优先于在目标级别定义的目录, Xcode 生成器除外。
相对路径不应直接添加到该属性中。
INCLUDE_DIRECTORIES 的内容可以使用语法 $<…> 的“生成器表达式” 。但是, Xcode 不支持 per-config per-source 设置,因此该生成器不允许依赖于构建配置的表达式。
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
创建一个缓存条目,或者一个普通变量,如果指定了 NO_CACHE ,由 命名来存储这个命令的结果。如果找到目录中的文件,则结果存储在变量中,除非清除变量,否则不会重复搜索。如果什么也没找到,结果将是 -NOTFOUND 。
find_path ( name1 [path1 path2 ...])find_path (name | NAMES name1 [name2 ...][HINTS [path | ENV var]... ][PATHS [path | ENV var]... ][REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)][PATH_SUFFIXES suffix1 [suffix2 ...]][DOC "cache documentation string"][NO_CACHE][REQUIRED][NO_DEFAULT_PATH][NO_PACKAGE_ROOT_PATH][NO_CMAKE_PATH][NO_CMAKE_ENVIRONMENT_PATH][NO_SYSTEM_ENVIRONMENT_PATH][NO_CMAKE_SYSTEM_PATH][NO_CMAKE_INSTALL_PREFIX][CMAKE_FIND_ROOT_PATH_BOTH |ONLY_CMAKE_FIND_ROOT_PATH |NO_CMAKE_FIND_ROOT_PATH])
NAMES
为目录中的文件指定一个或多个可能的名称。
当使用这个来指定有版本后缀和没有版本后缀的名称时,我们建议先指定没有版本的名称,这样就可以在发行版提供的软件包之前找到本地构建的软件包。
HINTS, PATHS
除了默认位置,还指定要搜索的目录。该 ENV var
子选项读取系统环境变量的路径。
在 3.24 版更改: 在 Windows
平台上,可以使用专用语法将注册表查询作为目录的一部分。在所有其他平台上,此类规范将被忽略。
REGISTRY_VIEW
3.24版的新内容。
指定必须查询哪些注册表视图。此选项仅在 Windows
平台上有意义,在其他平台上将被忽略。如果未指定,则在 CMP0134
策略为 NEW
时使用 TARGET
视图。策略为 OLD
时的默认视图,请参阅 CMP0134
。 CMP0134
NEW
CMP0134
OLD
64
查询 64 位注册表。在 32 位 Windows 上,它始终返回字符串 /REGISTRY-NOTFOUND
。
32
查询32位注册表。
64_32
查询两个视图( 64
和 32
)并为每个视图生成路径。
32_64
查询两个视图( 32
和 64
)并为每个视图生成路径。
HOST
查询与主机架构匹配的注册表: 64
位Windows为64,32位Windows为 32
。
TARGET
查询与 CMAKE_SIZEOF_VOID_P
变量指定的体系结构匹配的注册表。如果未定义,则回退到 HOST
视图。
BOTH
查询两个视图( 32
和 64
)。顺序取决于以下规则: 如果定义了 CMAKE_SIZEOF_VOID_P
变量,请根据该变量的内容使用以下视图:
8
: 64_32
4
: 32_64
如果没有定义 CMAKE_SIZEOF_VOID_P
变量,依赖主机的架构:
64_32
32
PATH_SUFFIXES
在每个目录位置下面指定额外的子目录进行检查,否则视为无效。
DOC
指定 缓存条目的文档字符串。
NO_CACHE
3.21版中的新内容。
搜索的结果将被存储在一个普通的变量中,而不是缓存条目。
Note
如果该变量在调用前已经被设置(作为普通变量或缓存变量),那么搜索将不会发生。
Warning
这个选项应该谨慎使用,因为它可能大大增加重复配置步骤的成本。
REQUIRED
3.18版本中的新功能。
如果没有找到任何东西,则停止处理并发出错误信息,否则在下一次用相同的变量调用find_path时,将再次尝试搜索。
如果指定了 NO_DEFAULT_PATH
,则不会将其他路径添加到搜索中。如果未指定 NO_DEFAULT_PATH
,则搜索过程如下:
3.12版中的新增功能:如果从查找模块中调用或由对 find_package(
的调用加载的任何其他脚本中调用,则搜索前缀对于要查找的当前包是唯一的。具体来说,请查看
CMake变量和
环境变量。包的根变量作为堆栈维护,因此,如果从嵌套查找模块或配置包中调用,则将在当前模块或包的路径之后搜索父级查找模块或配置包的根路径。换句话说,搜索顺序为
, ENV{
,
, ENV{
等等。如果传递了 NO_PACKAGE_ROOT_PATH
或将 CMAKE_FIND_USE_PACKAGE_ROOT_PATH
设置为 FALSE
,则可以跳过此操作。请参阅策略 CMP0074
。
/include/
如果设置了 CMAKE_LIBRARY_ARCHITECTURE
,则为 / include / ,如果 _ROOT
CMake变量和 _ROOT
环境变量中的每个
为 /include
,则设置为 / include。 find_package()
在特定于 cmake 的缓存变量中指定的搜索路径。这些旨在通过 -DVAR=value
在命令行上使用。这些值被解释为分号分隔的列表。 NO_CMAKE_PATH
或将 CMAKE_FIND_USE_CMAKE_PATH
设置为 FALSE
,则可以跳过此操作。
/include/
如果 CMAKE_LIBRARY_ARCHITECTURE
是集,而 /include
用于每个
在 CMAKE_PREFIX_PATH
CMAKE_INCLUDE_PATH
CMAKE_FRAMEWORK_PATH
在特定于cmake的环境变量中指定的搜索路径。这些意在用户的外壳配置进行设置,并因此使用主机的本地路径分隔( ;
在Windows和 :
在UNIX上)。这可如果跳过 NO_CMAKE_ENVIRONMENT_PATH
传递或通过设置 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH
到 FALSE
。
/include/
如果 CMAKE_LIBRARY_ARCHITECTURE
是集,而 /include
用于每个
在 CMAKE_PREFIX_PATH
CMAKE_INCLUDE_PATH
CMAKE_FRAMEWORK_PATH
搜索“ HINTS
选项指定的路径。这些应该是系统自省计算的路径,例如已经找到的另一个项目的位置所提供的提示。硬编码的猜测应使用 PATHS
选项指定。
搜索标准系统环境变量。这可如果跳过 NO_SYSTEM_ENVIRONMENT_PATH
传递或通过设置 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH
到 FALSE
。
INCLUDE
和 PATH
中的目录。/include/
如果 CMAKE_LIBRARY_ARCHITECTURE
被设置,并 /include
用于每个 /[s]bin
在 PATH
,和 /include
在其他条目 PATH
。搜索当前系统的 Platform 文件中定义的 cmake 变量。 NO_CMAKE_INSTALL_PREFIX
或将 CMAKE_FIND_USE_INSTALL_PREFIX
设置为 FALSE
,则可以跳过 CMAKE_INSTALL_PREFIX
和 CMAKE_STAGING_PREFIX
的搜索。 NO_CMAKE_SYSTEM_PATH
或将 CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
设置为 FALSE
,则可以跳过所有这些位置。 NO_CMAKE_INSTALL_PREFIX
CMAKE_FIND_USE_INSTALL_PREFIX
FALSE
NO_CMAKE_SYSTEM_PATH
CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
FALSE
/include/
如果 CMAKE_LIBRARY_ARCHITECTURE
是集,而 /include
用于每个
在 CMAKE_SYSTEM_PREFIX_PATH
CMAKE_SYSTEM_INCLUDE_PATH
CMAKE_SYSTEM_FRAMEWORK_PATH
这些变量包含的平台路径是通常包含已安装软件的位置。对于基于UNIX的平台,示例为 /usr/local
。
搜索PATHS选项或命令的简写版中指定的路径。这些通常是硬编码的猜测。
CMake给我们提供了find_package()命令用来查找依赖包,理想情况下,一句find_package()命令就能把一整个依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到,后续只管用就好了。
- 需要注意的是:
version: 版本合适(大版本号相同)
EXACT: 版本必须一致
QUIET: 没找到包也不会报错
REQUIRED: 必须找到该包,否则停止
find_package( [version] [EXACT] [QUIET] [REQUIRED])
cmake设置第三方包的头文件目录和库文件位置,是通过查询.cmake文件实现的,有两种命名形式,Find.cmake或者Config.cmake。
.cmake文件一般在第三方包编译和安装时会自动安装到$CMAKE_PREFIX_PATH/lib/cmake/等文件夹中,比如/usr/lib/cmake/,/usr/local/lib/cmake等等。
find_package()的工作就是在特定路径下查找第三方包.cmake文件。这些路径包括设定查询路径与默认查询路径。
设定查询路径通过cmake中的CMAKE_MODULE_PATH关键字设置寻找.cmake的位置:
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
上面的指令把工程根目录下的cmake文件夹添加为.cmake文件搜索路径,是优先搜索的路径。
另外,还可以直接设置某个包的.cmake位置:
set(OpenCV_DIR /path_to_opencv)
find_package(OpenCV)
上面的指令使find_package()寻找OpenCV时,最优先查找/path_to_opencv路径下的.cmake文件。
如果没有设定查询路径,或者在设定查询路径没有找到合适的.cmake时,cmake继续在默认查询路径中寻找.cmake文件,这些默认查询路径有:
PATH
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
如果PATH路径为/bin或/sbin文件夹,则从上一级目录查找。
以默认路径为根目录,cmake将检查根目录下的/lib/cmake,/lib//cmake,/share/cmake下寻找.cmake文件,根据.cmake生成对应的头文件目录和库文件路径。
指定链接给定目标和/或其依赖项时要使用的库或标志。来自链接库目标的使用要求将被传播。目标依赖项的使用要求会影响其自身源的编译。
TARGET_LINK_LIBRARIES(targetlibrary1 library2 ..)#比如(以下写法(包括备注中的)都可以):
TARGET_LINK_LIBRARIES(myProject hello),连接libhello.so库
TARGET_LINK_LIBRARIES(myProject libhello.a)
TARGET_LINK_LIBRARIES(myProject libhello.so)#再如:
TARGET_LINK_LIBRARIES(myProject libeng.so) #这些库名写法都可以。
TARGET_LINK_LIBRARIES(myProject eng)
TARGET_LINK_LIBRARIES(myProject -leng)
指定链接器在链接给定目标时应该搜索库的路径。每项可以是绝对路径或相对路径,后者被解释为相对于当前源目录。这些项目将被添加到链接命令中。
命名的 必须由诸如 add_executable() 或 add_library() 之类的命令创建,并且不能为ALIAS target。
需要 INTERFACE , PUBLIC 和 PRIVATE 关键字来指定其后各项的范围。
PRIVATE 和 PUBLIC 项目将填充 的 LINK_DIRECTORIES 属性。
PUBLIC 和 INTERFACE 项目将填充 的 INTERFACE_LINK_DIRECTORIES 属性(“ 导入的目标”仅支持 INTERFACE 项目)。
每个项目都指定一个链接目录,如果有必要,在将其添加到相关属性之前,它将转换为绝对路径。重复要求相同 按调用顺序附加项目。
target_link_directories( [BEFORE] [items1...][ [items2...] ...])
# cmake 最低版本号要求
cmake_minimum_required(VERSION 2.8)#设置project name
project(test_streamer)#设置编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")# aux_source_directory会查找指定目录下的所有源文件,并将结果存入指定变量名
# 这里是将当前目录下的所有源文件存进变量SRC_LIST
aux_source_directory(. SRC_LIST)# 设置ffmpeg依赖库及头文件所在目录,并存进指定变量
set(ffmpeg_libs_DIR /home/myn/libs/lib)
set(ffmpeg_headers_DIR /home/myn/libs/include)#用find_package引入外部依赖包
find_package(OpenCV REQUIRED )#对于find_package找不到的外部依赖库,可以用add_library添加
# SHARED表示添加的是动态库
# IMPORTED表示是引入已经存在的动态库
add_library( avcodec SHARED IMPORTED )#指定所添加依赖库的导入路径
set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavcodec.so )add_library( avfilter SHARED IMPORTED )
set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavfilter.so )add_library( swresample SHARED IMPORTED )
set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswresample.so )add_library( swscale SHARED IMPORTED )
set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libswscale.so )add_library( avformat SHARED IMPORTED )
set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavformat.so )add_library( avutil SHARED IMPORTED )
set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${ffmpeg_libs_DIR}/libavutil.so )# 添加头文件路径到编译器的头文件搜索路径下,多个路径以空格分隔
include_directories( ${OpenCV_INCLUDE_DIRS} ${ffmpeg_headers_DIR} )# 添加一个可执行目标,名称可自己指定,本例是直接用工程名称命名的
# 该可执行目标是由SRC_LIST中所列出的源文件生成
add_executable(${PROJECT_NAME} ${SRC_LIST} )
# directory of opencv library
link_directories(${OpenCV_LIBRARY_DIRS} ${ffmpeg_libs_DIR} )# 链接目标文件与依赖库
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS} avcodec avformat avutil swresample swscale swscale avfilter )
上一篇:C++类模板参数