【學習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
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM