• Cmake 链接外部库



    简述

    • 指定库的路径
      • 链接时使用绝对路径方式
      • link_libraries():添加需要链接的库文件路径,注意这里是全路径,(不推荐)
    • 指定所需头文件的路径
      • include_directories():添加头文件路径到编译器的头文件搜索路径下,多个路径以空格分隔.
    • 其他
      • find_path():和find_library()类似,find_path()可以用来找任何文件.
      • find_package():引入外部依赖包.
    • 链接目标
      • find_library():查找/指定所需的库(推荐).
      • link_directories():指定第三方库所在路径(只有在生成target之前调用才会有效, 即需要放在ADD_EXECUTABLE()之前调用)
      • target_link_libraries:指定目标(exe或者so文件)需要包含的库
      • target_include_directories:指定目标(exe或者so文件)需要包含的头文件路径
      • target_link_options :向链接器添加额外的命令行选项

    语法

    • find_library(查找库)

    此命令用于查找库。创建一个缓存条目,或者一个普通变量,如果指定了 NO_CACHE ,由 命名来存储这个命令的结果。如果找到库,结果将存储在变量中,除非清除变量,否则不会重复搜索。如果什么也没找到,结果将是 -NOTFOUND 。
    通常指定NAMESHINTS即可.

    #A short-hand signature is:
    find_library (<VAR> name1 [path1 path2 ...])
    #The general signature is:
    find_library (
              <VAR>
              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]
    
             )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    find_library参数

    • NAMES

      为库指定一个或多个可能的名称。

      当使用这个来指定有版本后缀和没有版本后缀的名称时,我们建议先指定没有版本的名称,这样就可以在发行版提供的软件包之前找到本地构建的软件包。

    • HINTS, PATHS

      除了默认位置,还指定要搜索的目录。该 ENV var 子选项读取系统环境变量的路径。

      在 3.24 版更改: 在 Windows 平台上,可以使用专用语法将注册表查> 询作为目录的一部分。在所有其他平台上,此类规范将被忽略。

    • REGISTRY_VIEW

      3.24版的新内容。

      指定必须查询哪些注册表视图。此选项仅在 Windows 平台上有意义,在其他平台上将被忽略。如果未指定,则在 CMP0134 策略为 NEW 时使用 TARGET 视图。策略为 OLD 时的默认视图,请参阅 CMP0134CMP0134 NEW CMP0134 OLD

      64

      查询 64 位注册表。在 32 位 Windows 上,它始终返回字符串 /REGISTRY-> NOTFOUND

      32

      查询32位注册表。

      64_32

      查询两个视图( 6432 )并为每个视图生成路径。

      32_64

      查询两个视图( 3264 )并为每个视图生成路径。

    • HOST

      查询与主机架构匹配的注册表: 64 位Windows为64,32位Windows为 32

    • TARGET

      查询与CMAKE_SIZEOF_VOID_P变量指定的体系结构匹配的注册表。如果未定义,则回退到 HOST 视图。

    • BOTH

      查询两个视图( 3264 )。顺序取决于以下规则: 如果定义CMAKE_SIZEOF_VOID_P变量,请根据该变量的内容使用以下视图:

      • 8: 64_32
      • 4: 32_64

      如果没有定义
      CMAKE_SIZEOF_VOID_P
      变量,依赖主机的架构:

      • 64-bit: 64_32
      • 32-bit: 32
    • PATH_SUFFIXES

      在每个目录位置下面指定额外的子目录进行检查,否则视为无效。

    • DOC

      指定 缓存条目的文档字符串。

    • NO_CACHE

      3.21版中的新内容。

      搜索的结果将被存储在一个普通的变量中,而不是缓存条目。

      Note

      如果该变量在调用前已经被设置(作为普通变量或缓存变量),那么搜索将不会发生。

      Warning

      这个选项应该谨慎使用,因为它可能大大增加重复配置步骤的成本。

    • REQUIRED

      3.18版本中的新功能。

      如果没有找到,则停止处理,并发出错误信息,否则在下一次用相同的变量调用find_library时,将再次尝试搜索。

      如果指定了 NO_DEFAULT_PATH ,则不会将其他路径添加到搜索中。如果未指定 NO_DEFAULT_PATH ,则搜索过程如下:

      1. 3.12版中的新增功能:如果从查找模块中调用或由对 find_package() 的调用加载的任何其他脚本中调用,则搜索前缀对于要查找的当前包是唯一的。
        具体来说,请查看 _ROOT CMake变量和 _ROOT 环境变量。
        包的根变量作为堆栈维护,因此,如果从嵌套查找模块或配置包中调用,则将在当前模块或包的路径之后搜索父级查找模块或配置包的根路径。
        换句话说,搜索顺序为 _ROOTENV{_ROOT}_ROOTENV{_ROOT} 等等。
        如果传递了 NO_PACKAGE_ROOT_PATH 或将 CMAKE_FIND_USE_PACKAGE_ROOT_PATH 设置为 FALSE ,则可以跳过此操作。
        请参阅策略 CMP0074

      2. 在特定于 cmake 的缓存变量中指定的搜索路径。这些旨在通过 -DVAR=value 在命令行上使用。这些值被解释为分号分隔的列表
        NO_CMAKE_PATH 或将 CMAKE_FIND_USE_CMAKE_PATH 设置为 FALSE ,则可以跳过此操作。

      3. 在特定于cmake的环境变量中指定的搜索路径。这些意在用户的外壳配置进行设置,并因此使用主机的本地路径分隔( ; 在Windows和 : 在UNIX上)。这可如果跳过 NO_CMAKE_ENVIRONMENT_PATH 传递或通过设置 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATHFALSE

      4. 搜索“ HINTS 选项指定的路径。这些应该是系统自省计算的路径,例如已经找到的另一个项目的位置所提供的提示。硬编码的猜测应使用 PATHS 选项指定。

      5. 搜索标准系统环境变量。这可如果跳过 NO_SYSTEM_ENVIRONMENT_PATH 传递或通过设置 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATHFALSE

        • LIBPATH 中的目录。
        • 在Windows主机: /lib/ 如果 CMAKE_LIBRARY_ARCHITECTURE 是集,而 /lib 用于每个 /[s]binPATH ,和 /lib 用于其他条目 PATH
      6. 搜索当前系统的 Platform 文件中定义的 cmake 变量。 NO_CMAKE_INSTALL_PREFIX 或将 CMAKE_FIND_USE_INSTALL_PREFIX 设置为 FALSE ,则可以跳过 CMAKE_INSTALL_PREFIXCMAKE_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

        这些变量包含的平台路径是通常包含已安装软件的位置。对于基于UNIX的平台,示例为 /usr/local 。查询两个视图( 3264 )。
        顺序取决于以下规则: 如果定义了 CMAKE_SIZEOF_VOID_P 变量,请根据该变量的内容使用以下视图:

        • 8: 64_32
        • 4: 32_64

        如果没有定义 CMAKE_SIZEOF_VOID_P 变量,依赖主机的架构:

        • 64-bit: 64_32
        • 32-bit: 32
      7. 搜索PATHS选项或命令的简写版中指定的路径。这些通常是硬编码的猜测.


    • include_directories(添加头文件目录)

    它相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用(这里特指c++。c和Java中用法类似)。
    此属性包含一个以分号分隔的路径列表,并将在此源文件构建时添加到包含目录列表中。由于技术限制,这些目录将优先于在目标级别定义的目录, Xcode 生成器除外。
    相对路径不应直接添加到该属性中。
    INCLUDE_DIRECTORIES 的内容可以使用语法 $<…> 的“生成器表达式” 。但是, Xcode 不支持 per-config per-source 设置,因此该生成器不允许依赖于构建配置的表达式。

    include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
    
    • 1

    • find_path(查找包含命名文件的目录)

    创建一个缓存条目,或者一个普通变量,如果指定了 NO_CACHE ,由 命名来存储这个命令的结果。如果找到目录中的文件,则结果存储在变量中,除非清除变量,否则不会重复搜索。如果什么也没找到,结果将是 -NOTFOUND 。

    find_path (<VAR> name1 [path1 path2 ...])
    
    find_path (
    
              <VAR>
              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]
    
             )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    find_path 参数

    • NAMES

    为目录中的文件指定一个或多个可能的名称。

    当使用这个来指定有版本后缀和没有版本后缀的名称时,我们建议先指定没有版本的名称,这样就可以在发行版提供的软件包之前找到本地构建的软件包。

    • HINTS, PATHS

      除了默认位置,还指定要搜索的目录。该 ENV var 子选项读取系统环境变量的路径。

      在 3.24 版更改: 在 Windows
      平台上,可以使用专用语法将注册表查询作为目录的一部分。在所有其他平台上,此类规范将被忽略。

    • REGISTRY_VIEW

      3.24版的新内容。

      指定必须查询哪些注册表视图。此选项仅在 Windows 平台上有意义,在其他平台上将被忽略。如果未指定,则在 CMP0134 策略为 NEW 时使用 TARGET 视图。策略为 OLD 时的默认视图,请参阅 CMP0134CMP0134 NEW CMP0134 OLD

      64

      查询 64 位注册表。在 32 位 Windows 上,它始终返回字符串 /REGISTRY-NOTFOUND

      32

      查询32位注册表。

      64_32

      查询两个视图( 6432 )并为每个视图生成路径。

      32_64

      查询两个视图( 3264 )并为每个视图生成路径。

    • HOST

      查询与主机架构匹配的注册表: 64 位Windows为64,32位Windows为 32

    • TARGET

      查询与 CMAKE_SIZEOF_VOID_P 变量指定的体系结构匹配的注册表。如果未定义,则回退到 HOST 视图。

    • BOTH

      查询两个视图( 3264 )。顺序取决于以下规则: 如果定义了 CMAKE_SIZEOF_VOID_P 变量,请根据该变量的内容使用以下视图:

    • 8: 64_32

    • 4: 32_64

    如果没有定义 CMAKE_SIZEOF_VOID_P 变量,依赖主机的架构:

    • 64-bit: 64_32

    • 32-bit: 32

    • PATH_SUFFIXES

      在每个目录位置下面指定额外的子目录进行检查,否则视为无效。

    • DOC

      指定 缓存条目的文档字符串。

    • NO_CACHE

      3.21版中的新内容。

      搜索的结果将被存储在一个普通的变量中,而不是缓存条目。

      Note

      如果该变量在调用前已经被设置(作为普通变量或缓存变量),那么搜索将不会发生。

      Warning

      这个选项应该谨慎使用,因为它可能大大增加重复配置步骤的成本。

    • REQUIRED

      3.18版本中的新功能。

      如果没有找到任何东西,则停止处理并发出错误信息,否则在下一次用相同的变量调用find_path时,将再次尝试搜索。

      如果指定了 NO_DEFAULT_PATH ,则不会将其他路径添加到搜索中。如果未指定 NO_DEFAULT_PATH ,则搜索过程如下:

      1. 3.12版中的新增功能:如果从查找模块中调用或由对 find_package() 的调用加载的任何其他脚本中调用,则搜索前缀对于要查找的当前包是唯一的。具体来说,请查看 _ROOT CMake变量和 _ROOT 环境变量。包的根变量作为堆栈维护,因此,如果从嵌套查找模块或配置包中调用,则将在当前模块或包的路径之后搜索父级查找模块或配置包的根路径。换句话说,搜索顺序为 _ROOTENV{_ROOT}_ROOTENV{_ROOT} 等等。如果传递了 NO_PACKAGE_ROOT_PATH 或将 CMAKE_FIND_USE_PACKAGE_ROOT_PATH 设置为 FALSE ,则可以跳过此操作。请参阅策略 CMP0074

      2. 在特定于 cmake 的缓存变量中指定的搜索路径。这些旨在通过 -DVAR=value 在命令行上使用。这些值被解释为分号分隔的列表NO_CMAKE_PATH 或将 CMAKE_FIND_USE_CMAKE_PATH 设置为 FALSE ,则可以跳过此操作。

      3. 在特定于cmake的环境变量中指定的搜索路径。这些意在用户的外壳配置进行设置,并因此使用主机的本地路径分隔( ; 在Windows和 : 在UNIX上)。这可如果跳过 NO_CMAKE_ENVIRONMENT_PATH 传递或通过设置 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATHFALSE

      4. 搜索“ HINTS 选项指定的路径。这些应该是系统自省计算的路径,例如已经找到的另一个项目的位置所提供的提示。硬编码的猜测应使用 PATHS 选项指定。

      5. 搜索标准系统环境变量。这可如果跳过 NO_SYSTEM_ENVIRONMENT_PATH 传递或通过设置 CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATHFALSE

        • INCLUDEPATH 中的目录。
        • 在Windows主机: /include/ 如果 CMAKE_LIBRARY_ARCHITECTURE 被设置,并 /include 用于每个 /[s]binPATH ,和 /include 在其他条目 PATH
      6. 搜索当前系统的 Platform 文件中定义的 cmake 变量。 NO_CMAKE_INSTALL_PREFIX 或将 CMAKE_FIND_USE_INSTALL_PREFIX 设置为 FALSE ,则可以跳过 CMAKE_INSTALL_PREFIXCMAKE_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

        这些变量包含的平台路径是通常包含已安装软件的位置。对于基于UNIX的平台,示例为 /usr/local

      7. 搜索PATHS选项或命令的简写版中指定的路径。这些通常是硬编码的猜测。


    • find_package(查找依赖包)

    CMake给我们提供了find_package()命令用来查找依赖包,理想情况下,一句find_package()命令就能把一整个依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到,后续只管用就好了。

    • 需要注意的是:
      version: 版本合适(大版本号相同)
      EXACT: 版本必须一致
      QUIET: 没找到包也不会报错
      REQUIRED: 必须找到该包,否则停止
    find_package(<PackageName> [version] [EXACT] [QUIET] [REQUIRED])
    
    • 1

    find_package查询路径

    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)
    
    • 1
    • 2

    上面的指令使find_package()寻找OpenCV时,最优先查找/path_to_opencv路径下的.cmake文件。


    默认路径

    如果没有设定查询路径,或者在设定查询路径没有找到合适的.cmake时,cmake继续在默认查询路径中寻找.cmake文件,这些默认查询路径有:

    PATH
    CMAKE_PREFIX_PATH
    CMAKE_FRAMEWORK_PATH
    CMAKE_APPBUNDLE_PATH
    
    • 1
    • 2
    • 3
    • 4

    如果PATH路径为/bin或/sbin文件夹,则从上一级目录查找。
    以默认路径为根目录,cmake将检查根目录下的/lib/cmake,/lib//cmake,/share/cmake下寻找.cmake文件,根据.cmake生成对应的头文件目录和库文件路径。


    编写属于自己的Findxxx.cmake文件

    此内容在我的另一篇博客里专门讲解:编写属于自己的Findxxx.cmake文件


    • target_link_libraries(设置要链接的库文件的名称)

    指定链接给定目标和/或其依赖项时要使用的库或标志。来自链接库目标的使用要求将被传播。目标依赖项的使用要求会影响其自身源的编译。

    TARGET_LINK_LIBRARIES(targetlibrary1 <debug | optimized> 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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    • link_directories(添加需要链接的库文件目录)

    指定第三方库所在路径,比如,你的动态库在/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.
    
    • 1
    • 2
    • 3
    • 4

    • link_libraries(添加需要链接的库文件路径,注意这里是全路径)

    添加链接器将在其中查找库的目录,link_libraries 命令是全局性的,即对所有目标文件都有效。如果需要对某个特定的目标文件链接库,可以使用 target_link_libraries 命令。此外,为了避免链接库的顺序问题,建议使用 target_link_libraries 命令来代替 link_libraries 命令。

    link_libraries([item1 [item2 [...]]]
                   [[debug|optimized|general] <item>] ...)
    # 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.
    
    • 1
    • 2
    • 3
    • 4

    • target_link_directories(为目标添加链接目录)

    指定链接器在链接给定目标时应该搜索库的路径。每项可以是绝对路径或相对路径,后者被解释为相对于当前源目录。这些项目将被添加到链接命令中。
    命名的 必须由诸如 add_executable() 或 add_library() 之类的命令创建,并且不能为ALIAS target。
    需要 INTERFACE , PUBLIC 和 PRIVATE 关键字来指定其后各项的范围。
    PRIVATE 和 PUBLIC 项目将填充 的 LINK_DIRECTORIES 属性。
    PUBLIC 和 INTERFACE 项目将填充 的 INTERFACE_LINK_DIRECTORIES 属性(“ 导入的目标”仅支持 INTERFACE 项目)。
    每个项目都指定一个链接目录,如果有必要,在将其添加到相关属性之前,它将转换为绝对路径。重复要求相同 按调用顺序附加项目。

    target_link_directories(<target> [BEFORE]
     <INTERFACE|PUBLIC|PRIVATE> [items1...]
     [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
    
    
    • 1
    • 2
    • 3
    • 4

    • target_link_options (向链接器添加额外的命令行选项)

    target_link_options(<target> [BEFORE]
                       [AFTER] <option> <option> ...)
    
    • 1
    • 2

    该命令用于向目标文件的链接器添加额外的命令行选项。其中,参数说明如下:
    :目标文件的名称。
    [BEFORE] 和 [AFTER]:可选参数,用于指定选项添加的位置。默认情况下,选项添加在最后。
    :要添加的命令行选项。
    注意,该命令只对在其之后的目标文件有效。如果需要对之前的目标文件也添加选项,可以使用 CMAKE_EXE_LINKER_FLAGS、CMAKE_SHARED_LINKER_FLAGS 或 CMAKE_MODULE_LINKER_FLAGS 变量。

    target_link_options 命令用于向链接器添加额外的命令行选项。例如:
    target_link_options(my_app PRIVATE "-Wl,-rpath,/path/to/lib")
    在这个例子中,我们向链接器添加 -Wl,-rpath,/path/to/lib 选项,告诉链接器在运行时动态链接库时搜索 /path/to/lib 目录。


    示例

    示例一:查找ffmpeg库

    # 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 )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    示例二:使用find_path查找

    cmake_minimum_required(VERSION 3.0)
    
    project(find_example)
    
    # 查找libfoo.so的头文件路径
    find_path(FOO_INCLUDE_DIR foo.h PATHS /usr/local/include /usr/include)
    if (FOO_INCLUDE_DIR)
        message(STATUS "Found foo.h at ${FOO_INCLUDE_DIR}")
    else()
        message(FATAL_ERROR "Could not find foo.h")
    endif()
    
    # 查找libbar.a的库文件路径
    find_path(BAR_LIB_DIR libbar.a PATHS /usr/local/lib /usr/lib)
    if (BAR_LIB_DIR)
        message(STATUS "Found libbar.a at ${BAR_LIB_DIR}")
    else()
        message(FATAL_ERROR "Could not find libbar.a")
    endif()
    
    # 查找第三方库的源代码路径
    find_path(THIRD_PARTY_SRC_DIR third_party_lib.cpp PATHS ${CMAKE_SOURCE_DIR} /usr/local/src)
    if (THIRD_PARTY_SRC_DIR)
        message(STATUS "Found third_party_lib.cpp at ${THIRD_PARTY_SRC_DIR}")
    else()
        message(FATAL_ERROR "Could not find third_party_lib.cpp")
    endif()
    
    # 查找数据文件路径
    find_path(DATA_FILE_DIR data.txt PATHS ${CMAKE_SOURCE_DIR} /usr/local/data)
    if (DATA_FILE_DIR)
        message(STATUS "Found data.txt at ${DATA_FILE_DIR}")
    else()
        message(FATAL_ERROR "Could not find data.txt")
    endif()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    示例三:使用target_link_options()指定编译参数

    cmake_minimum_required(VERSION 3.5)
    
    project(test)
    
    # 创建一个可执行文件
    add_executable(my_exe main.cpp)
    
    # 指定链接器选项
    target_link_options(my_exe PRIVATE
      # 1. 添加链接库的搜索路径
      -L/path/to/lib
      # 2. 添加需要链接的库文件
      -lfoo
      # 3. 添加链接器标志
      -Wl,-rpath=/path/to/lib
      # 4. 禁止链接标准库
      -nostdlib
      # 5. 调试信息
      -g
      # 6. 优化等级
      -O2
      # 7. 添加链接器脚本文件
      -Tpath/to/linker_script.ld
      # 8. 强制链接所有符号
      --whole-archive
      # 9. 隐藏所有符号
      --exclude-libs=ALL
      # 10. 链接指定版本的库文件
      -lfoo.so.1
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    5G车载网关让医院无人配送车“灵活“起来
    jsbridge实战1:xcode swift 构建iOS app
    刷题记录:牛客NC211219电话网络
    element ui框架(登录窗口)
    leetcode算法每天一题010: 正则表达式,判断pattern和string是否匹配(动态规划)
    PTA题目 A除以B
    【数据结构】快速排序
    mybatis-plus使用总结
    clickhouse基础介绍
    【第4篇】人工智能简介
  • 原文地址:https://blog.csdn.net/qq_21438461/article/details/127960337