CmakeList 組織編譯項目的基本用法

基本語句

外部編譯源碼

  • 文檔結構

    --projecct
       --main.cpp
       --class1.cpp
       --class1.h
       --Cmakelist.txt     
       --build
  • 項目名

PROJECCT(hello)

  • 版本說明

    CMAKE_MINIMUM_REQUIRED(VERSION 3.2)

  • 編譯可執行文件

    ADD_EXECUTABLE(hello main.cpp class1.cpp)

  • 或者用變量指定源文件

    SET(SRC_LIST main.cpp class1.h class1.cpp)

    ADD_EXECUTABLE(hello SRC_LIST)

    或者

    SET(SOURCE_FILES main.cpp class1.h class1.cpp)

    ADD_EXECUTABLE(hello SOURCE_FILES)

  • 消息提示添加

    MESSAGE(STATUS “this is BINARY dir ” ${PROJECT_BINARY_DIR})

    MESSAGE(STATUS “this is SOURCE dir ” ${PROJECT_SOURCE_DIR})

    其中PROJECT_BINARTY_DIR也可以寫作HELLO_BINARY_DIR,是build後存放二進制可執行文件的路徑。

    其中PROJECT_SOURCE_DIR也可以寫作HELLO_SOURCE_DIR,是項目路徑。

  • 編譯過程

    cd ~/project
    mkdir build
    cd build
    cmake ..
    make

    ..是父級目錄; .是當前目錄

    cmake後build裏會生成 makefile 文件

    make 後生成 hello.bin

    ./hello 運行程序

    清理工作:make clean

編譯靜/動態庫

簡單靜態庫

假設想要生成一個靜態庫libclass.a

  • 文檔結構

    --project
    --main.cpp
    --class.cpp
    --class.h
    --Cmakelist.txt
    --build

  • CmakeList.txt如下

    PROJECT(HELLO)
    CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
    ADD_EXECUTABLE(hello hello.cpp)
    ADD_LIBRARY(class class.cpp)

    其中ADD_LIBRARY(class class.cpp)可以用下面等代碼替換

    SET(LIBCLASS_SRC hello.cpp)

    ADD_LIBRARY(class ${LIBCLASS_SRC})

生成動態庫

  • 文檔結構
--projecct
     --lib
       --hello.cpp
       --hello.h
       --CmakeList.txt
     --CmakeList.txt
     --build
  • project文件夾下的CmakeList如下

    PROJECT(hellolib)
    ADD_SUBDIRECTORY(lib)
  • lib文件夾下的CmakeList如下

    SETLIBHELLO_SRC class.cpp
    ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})添加

    編譯後會在build/lib/下生成 libhello.so

  • 語句ADD_LIBRARY(libname[SHARED|STATIC|MODULE][EXCLUDE_FROM_ALL]source1 source2 ...)

    SHARED –動態庫

    STATIC –靜態庫

  • 指定動態庫生成的位置

    可以在主工程的CmakeList.txt中添加一行

    SET(LIBRARY_OUTPUT_PATH <path_to_lib>)

同時生成同名的靜態庫與動態庫

  • 在上面的動態庫工程中,如果在ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})後添加ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})發現build/lib/下只有靜態庫 libhello.a

    這是因爲hello作爲一個target是不能重命名的

  • ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})改成ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})重新編譯。可以得到libhello.solibhello_static.a

  • 爲了得到同名的靜態庫和動態庫,用指令:

    SET_TARGET_PROPERTIES(target1 target2 ...PROPERTIES prop1 value1 prop2 value2 ...)

    在lib/CmakeList.txt中這麼寫:

    SET(LIB_SRC hello.cpp hello.h)
    ADD_LIBRARY(hello SHARED ${LIB_SRC})
    ADD_LIBRARY(hello_static STATIC ${LIB_SRC})
    SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

    重新編譯就可以得到 libhello.so 和 libhello.a 兩個庫。

  • cmake 在構建一個新的 target 時,會嘗試清理掉其他使用這個名字的庫,因爲,在構建 libhello.a 時,
    就會清理編譯前已經存在的 libhello.so。如果分批編譯,又要防止同名庫被清理,可以在lib/CmakeList.txt中添加:

    SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

使用外部庫和頭文件

以手動添加OPENCV爲例子:

頭文件路徑/usr/local/include也可以通過 ~/.bashrc 添加

opencv常用的庫 libopencv_core.so libopencv_highgui.so libopencv_imgproc.so

  • 文件結構

    --project
    --src
      --main.cpp
      --CmakeList.txt
    --CmakeList.txt
    --build
  • project/CmakeList.txt:

    PROJECT(main)
    ADD_SUBDIRECTORY(src)
  • src/CmakeList.txt:

    ADD_EXECUTABLE(main main.cpp)
    INCLUDE_DIRECTORIES(/usr/local/include/)
    TARGET_LINK_LIBRARIES(main /usr/local/lib/libopencv_core.so)

添加頭文件搜索目錄

INCLUDE_DIRECTORIES(/usr/local/include)

添加庫搜索目錄

LINK_DIRECTORIES(/usr/local/opencv/lib)

添加外部庫鏈接

target_link_libraries(main /usr/local/lib/libopencv_core.so usr/local/lib/libopencv_highgui.so  /usr/local/lib/libopencv_imgproc.so)

TARGET_LINK_LIBRARIES(main hello)也可以寫成

TARGET_LINK_LIBRARIES(main libhello.so)

使用FIND_PACKAGES 添加 OPENCV

cmake_minimum_required(VERSION 3.5.1)
project(heatmap)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp heat.cpp heat.h)

find_package(OpenCV REQUIRED)
set(OpenCV_FOUND TRUE CACHE BOOL "" FORCE)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(heatmap ${OpenCV_LIBS})

add_executable(heatmap ${SOURCE_FILES})
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章