zoukankan      html  css  js  c++  java
  • 【学习cmake】cmake如何使用链接库 (link_directories, LINK_LIBRARIES, target_link_libraries,FIND_PACKAGE)实践篇2

    cmake中添加引用动态链接和静态链接库

    ADD_EXECUTABLE(a.out ./main.cpp)
    TARGET_LINK_LIBRARIES(a.out /usr/lib/libeg.so)

    动态库的添加:

    link_directories(${PROJECT_SOURCE_DIR}/lib) #添加动态连接库的路径
    target_link_libraries(project_name -lmxnet ) #添加libmxnet.so
    静态库的添加:

    add_library(mxnet STATIC IMPORTED)
    set_property(TARGET mxnet PROPERTY IMPORTED_LOCATION /path/to/libmxnet.a)
    target_link_libraries(project_name mxnet ) #添加libmxnet.a
     

    1.  
      # 声明要求的 cmake 最低版本
    2.  
      cmake_minimum_required( VERSION 2.8 )
    3.  
       
    4.  
      # 声明一个 cmake 工程
    5.  
      project(useHello)
    6.  
       
    7.  
      # 设置编译模式
    8.  
      set( CMAKE_BUILD_TYPE "Debug" )
    9.  
       
    10.  
      # VAR变量代表找到的库全路径,包含库文件名
    11.  
      #FIND_LIBRARY(libhello_shared /home/ubuntu/ch2/useHello)#bug
    12.  
       
    13.  
      include_directories (${useHello_SOURCE_DIR})
    14.  
      MESSAGE(${useHello_SOURCE_DIR})#${PROJECT_SOURCE_DIR}
    15.  
       
    16.  
      #增加src为link目录w-1
    17.  
      # link_directories(${PROJECT_SOURCE_DIR})#${PROJECT_SOURCE_DIR}
    18.  
      # MESSAGE(${PROJECT_SOURCE_DIR})
    19.  
      #增加src为link目录w-2
    20.  
      # link_directories("/home/ubuntu/ch2/useHello")
    21.  
      link_directories(/home/ubuntu/ch2/useHello)# "/"=/ 引号 可有可无
    22.  
      # 添加一个可执行程序
    23.  
       
    24.  
      add_executable(useHello useHello.cpp )
    25.  
      # 将库文件链接到可执行程序上
    26.  
      # target_link_libraries( useHello hello)
    27.  
      # target_link_libraries( useHello hello_shared )# w-1
    28.  
      target_link_libraries( useHello -lhello)#hello_shared=lhello # w-2

    #增加src为link目录  link_directories

    # 将库文件链接到可执行程序上 target_link_libraries

    1.  
      #增加src为link目录w-1
    2.  
      link_directories(${PROJECT_SOURCE_DIR})#${PROJECT_SOURCE_DIR}
    3.  
      # MESSAGE(${PROJECT_SOURCE_DIR})
    4.  
      #增加src为link目录w-2
    5.  
      # link_directories("/home/ubuntu/ch2/useHello")
    6.  
      link_directories(/home/ubuntu/ch2/useHello)# "/"=/ 引号 可有可无
    7.  
       
    8.  
      # 添加一个可执行程序
    9.  
      add_executable(useHello useHello.cpp )
    10.  
      # 将库文件链接到可执行程序上
    11.  
      # target_link_libraries( useHello hello)
    12.  
      target_link_libraries( useHello hello_shared )# w-1
    13.  
      # target_link_libraries( useHello -lhello)#hello_shared=lhello # w-2

    target_link_libraries与link_libraries 区别

    1.  
      target_link_libraries(useHello /home/ubuntu/ch2/useHello/libhello_shared.so)
    2.  
      # target_link_libraries(useHello "/home/ubuntu/ch2/useHello/libhello_shared.so")
    3.  
      # link_libraries(useHello "/home/ubuntu/ch2/useHello/libhello_shared.so")#bug
    4.  
      # link_libraries(useHello /home/ubuntu/ch2/useHello/libhello_shared.so)#bug #undefined reference to `printHello()

    路径错误

    target_link_libraries 全路径,绝对路径

    路径错误提示bug(路径拼写错误) “”  ""  ‘’英文双引号  或不加引号

    #bug #undefined reference to `printHello()
    #bug  #/usr/bin/ld: cannot find -l“home/ubuntu/ch2/usehello/libhello_shared.so”
    In function `main':useHello.cpp:6: undefined reference to `printHello()'
     

    LINK_LIBRARIES (添加需要链接的库文件路径,注意这里是全路径)
    List of direct link dependencies.

    比如:
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so")
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")

    也可以写成:
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")

    ————————————————————————————————————————


    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)

    与add_executable相对位置

    LINK_LIBRARIES (添加需要链接的库文件路径,注意这里是全路径) 在add_executable前面位置

    target_link_libraries 可以在add_executable后面位置

    一个简单的示例


    一个简单的示例(以下CMakeLists.txt效果相当,在ubuntu 12.04 + g++4.6下测试编译通过):

    方式一:

    cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
     
    include_directories("/opt/MATLAB/R2012a/extern/include")
     
    #directly link to the libraries.
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so")
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")
     
    #equals to below
    #LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")
     
    add_executable(myProject main.cpp) 

    1.  
      link_libraries("/home/ubuntu/ch2/useHello/libhello_shared.so")#前
    2.  
      # 添加一个可执行程序
    3.  
      add_executable(useHello useHello.cpp )

    方式二:
    cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
     
    include_directories("/opt/MATLAB/R2012a/extern/include")
     
    LINK_DIRECTORIES("/opt/MATLAB/R2012a/bin/glnxa64")
     
    add_executable(myProject main.cpp)
     
    target_link_libraries(myProject eng mx)
     
    #equals to below
    #target_link_libraries(myProject -leng -lmx)
    #target_link_libraries(myProject libeng.so libmx.so)

    1.  
      add_executable(useHello useHello.cpp )
    2.  
      # 将库文件链接到可执行程序上
    3.  
      target_link_libraries( useHello hello)#后
    4.  
      # target_link_libraries( useHello hello_shared )# w-1
    5.  
      # target_link_libraries( useHello -lhello)#hello_shared=lhello # w-2

    --------------------- 

    link_directories

    1.  
      #增加src为link目录w-1
    2.  
      # link_directories(${PROJECT_SOURCE_DIR})#${PROJECT_SOURCE_DIR}
    3.  
      # MESSAGE(${PROJECT_SOURCE_DIR})
    4.  
      #增加src为link目录w-2
    5.  
      # link_directories("/home/ubuntu/ch2/useHello")
    6.  
      # link_directories(/home/ubuntu/ch2/useHello)# "/"=/ 引号 可有可无

    link_directories, LINK_LIBRARIES, target_link_libraries使用总结

    INCLUDE_DIRECTORIES(添加头文件目录)
    它相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用(这里特指c++。c和Java中用法类似)。

    比如:
    include_directories("/opt/MATLAB/R2012a/extern/include")

    export CPLUS_INCLUDE_PATH=CPLUS_INCLUDE_PATH:$MATLAB/extern/include


    LINK_DIRECTORIES(添加需要链接的库文件目录)
    语法:
    link_directories(directory1 directory2 ...)

    它相当于g++命令的-L选项的作用,也相当于环境变量中增加LD_LIBRARY_PATH的路径的作用。

    比如:
    LINK_DIRECTORIES("/opt/MATLAB/R2012a/bin/glnxa64")

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MATLAB/bin/glnxa64


    LINK_LIBRARIES (添加需要链接的库文件路径,注意这里是全路径)
    List of direct link dependencies.

    比如:
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so")
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")

    也可以写成:
    LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")


    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)
    -----------------

    FIND_PACKAGE

    hello ---he  hell 不完整 错误提示

    CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
    Please set them or make sure they are set and tested correctly in the CMake files:
    HELLO_LIB
        linked by target "useHello" in directory /home/ubuntu/ch2/useHello

    -- Configuring incomplete, errors occurred!

    FIND_LIBRARY

    1.  
      # VAR变量代表找到的库全路径,包含库文件名
    2.  
      FIND_LIBRARY(HELLO_LIB hello /usr/lib /home/ubuntu/ch2/useHello /usr/local/lib NO_DEFAULT_PATH)
    3.  
      link_libraries(${HELLO_LIB})
    4.  
       
    5.  
      # 添加一个可执行程序
    6.  
      add_executable(useHello useHello.cpp )

    直接链接库目录路径

    1.  
      # 链接库目录路径
    2.  
      link_directories(${PROJECT_SOURCE_DIR})#${PROJECT_SOURCE_DIR}
    3.  
       
    4.  
      # 添加一个可执行程序
    5.  
      add_executable( useHello useHello.cpp )
    6.  
      # 将库文件链接到可执行程序上
    7.  
      target_link_libraries( useHello hello_shared )

    find_package

    FIND_PACKAGE( <name> [version] [EXACT] [QUIET] [NO_MODULE] [ [ REQUIRED | COMPONENTS ] [ componets... ] ] )

    用来调用预定义在 CMAKE_MODULE_PATH 下的 Find<name>.cmake 模块。

    也可以自己定义 Find<name>模块,将其放入工程的某个目录中,通过 SET(CMAKE_MODULE_PATH dir)设置查找路径,供工程FIND_PACKAGE使用。

    这条命令执行后,CMake 会到变量 CMAKE_MODULE_PATH 指示的目录中查找文件 Findname.cmake 并执行。

     区分FIND_LIBRARY        https://blog.csdn.net/KYJL888/article/details/78860077

    没有通过 cmake 生成供find_package使用的自定义模块

    https://blog.csdn.net/KYJL888/article/details/85113221
     

    --------------——————————————————————————————————

    如果想灵活一点,不把库的路径写死,那就类似这样(libeg.so):

    FIND_PACKAGE(eg REQUIRED)
    IF (EG_FOUND)
        INCLUDE_DIRECTORIES(${EG_INCLUDE_DIRS})
        SET(DEPLIBS ${DEPLIBS} ${EG_LIBRARIES})
    ENDIF ()

    # 下面可以有好多个FIND_PACKAGE(...)

    ADD_EXECUTABLE(a.out ./main.cpp)
    TARGET_LINK_LIBRARIES(a.out ${DEPLIBS})

    当然这是需要FindXXX.cmake文件支持的,cmake自带了一些(cmake --help-module-list),没有的话需要自己写

    CMake支持大写、小写、混合大小写的命令。

    1. 添加头文件目录INCLUDE_DIRECTORIES

    语法:

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

    它相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用。

    include_directories(../../../thirdparty/comm/include)

    2. 添加需要链接的库文件目录LINK_DIRECTORIES

    语法:

    link_directories(directory1 directory2 ...)

    它相当于g++命令的-L选项的作用,也相当于环境变量中增加LD_LIBRARY_PATH的路径的作用。

    link_directories("/home/server/third/lib")

    3. 查找库所在目录FIND_LIBRARY

    语法:

    1.  
      A short-hand signature is:
    2.  
       
    3.  
      find_library (<VAR> name1 [path1 path2 ...])
    4.  
      The general signature is:
    5.  
       
    6.  
      find_library (
    7.  
      <VAR>
    8.  
      name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
    9.  
      [HINTS path1 [path2 ... ENV var]]
    10.  
      [PATHS path1 [path2 ... ENV var]]
    11.  
      [PATH_SUFFIXES suffix1 [suffix2 ...]]
    12.  
      [DOC "cache documentation string"]
    13.  
      [NO_DEFAULT_PATH]
    14.  
      [NO_CMAKE_ENVIRONMENT_PATH]
    15.  
      [NO_CMAKE_PATH]
    16.  
      [NO_SYSTEM_ENVIRONMENT_PATH]
    17.  
      [NO_CMAKE_SYSTEM_PATH]
    18.  
      [CMAKE_FIND_ROOT_PATH_BOTH |
    19.  
      ONLY_CMAKE_FIND_ROOT_PATH |
    20.  
      NO_CMAKE_FIND_ROOT_PATH]
    21.  
      )

    例子如下:

    FIND_LIBRARY(RUNTIME_LIB rt /usr/lib  /usr/local/lib NO_DEFAULT_PATH)

    cmake会在目录中查找,如果所有目录中都没有,值RUNTIME_LIB就会被赋为NO_DEFAULT_PATH

    4. 添加需要链接的库文件路径LINK_LIBRARIES

    语法:

    link_libraries(library1 <debug | optimized> library2 ...)
    1.  
      # 直接是全路径
    2.  
      link_libraries(“/home/server/third/lib/libcommon.a”)
    1.  
      # 下面的例子,只有库名,cmake会自动去所包含的目录搜索
    2.  
      link_libraries(iconv)
    3.  
       
    4.  
      # 传入变量
    5.  
      link_libraries(${RUNTIME_LIB})
    1.  
      # 也可以链接多个
    2.  
      link_libraries("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")

    可以链接一个,也可以多个,中间使用空格分隔.

    5. 设置要链接的库文件的名称TARGET_LINK_LIBRARIES 

    语法:

    1.  
      target_link_libraries(<target> [item1 [item2 [...]]]
    2.  
      [[debug|optimized|general] <item>] ...)
    1.  
      # 以下写法都可以:
    2.  
      target_link_libraries(myProject comm) # 连接libhello.so库,默认优先链接动态库
    3.  
      target_link_libraries(myProject libcomm.a) # 显示指定链接静态库
    4.  
      target_link_libraries(myProject libcomm.so) # 显示指定链接动态库
    5.  
       
    6.  
      # 再如:
    7.  
      target_link_libraries(myProject libcomm.so)  #这些库名写法都可以。
    8.  
      target_link_libraries(myProject comm)
    9.  
      target_link_libraries(myProject -lcomm)

    6. 为工程生成目标文件
    语法:

    1.  
      add_executable(<name> [WIN32] [MACOSX_BUNDLE]
    2.  
      [EXCLUDE_FROM_ALL]
    3.  
      source1 [source2 ...])

    简单的例子如下:

    1.  
      add_executable(demo
    2.  
      main.cpp
    3.  
      )

    6. 最后贴一个完整的例子

    1.  
      cmake_minimum_required (VERSION 2.6)
    2.  
       
    3.  
      INCLUDE_DIRECTORIES(../../thirdparty/comm)
    4.  
       
    5.  
      FIND_LIBRARY(COMM_LIB comm ../../thirdparty/comm/lib NO_DEFAULT_PATH)
    6.  
      FIND_LIBRARY(RUNTIME_LIB rt /usr/lib /usr/local/lib NO_DEFAULT_PATH)
    7.  
       
    8.  
      link_libraries(${COMM_LIB} ${RUNTIME_LIB})
    9.  
       
    10.  
      ADD_DEFINITIONS(
    11.  
      -O3 -g -W -Wall
    12.  
      -Wunused-variable -Wunused-parameter -Wunused-function -Wunused
    13.  
      -Wno-deprecated -Woverloaded-virtual -Wwrite-strings
    14.  
      -D__WUR= -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DTIXML_USE_STL
    15.  
      )
    16.  
       
    17.  
       
    18.  
      add_library(lib_demo
    19.  
      cmd.cpp
    20.  
      global.cpp
    21.  
      md5.cpp
    22.  
      )
    23.  
       
    24.  
      link_libraries(lib_demo)
    25.  
      add_executable(demo
    26.  
      main.cpp
    27.  
      )
    28.  
       
    29.  
      # link library in static mode
    30.  
      target_link_libraries(demo libuuid.a)
    1.  
      另外,使用cmake生成makefile之后,make edit_cache可以编辑编译选项。
    2.  
       
    3.  
      不熟悉的命令可以去查找文档,贴个cmake3.0官方帮助文档地址
    4.  
      https://cmake.org/cmake/help/v3.0/index.html
     
  • 相关阅读:
    814. Binary Tree Pruning
    50. Pow(x, n)
    698. Partition to K Equal Sum Subsets
    416. Partition Equal Subset Sum
    150. Evaluate Reverse Polish Notation
    322. Coin Change
    Vulnerable Kerbals CodeForces
    D. Domino for Young
    C. Long Beautiful Integer
    B. Modulo Equality
  • 原文地址:https://www.cnblogs.com/lidabo/p/13803627.html
Copyright © 2011-2022 走看看