1. 程式人生 > >CMake 編譯靜態庫和動態庫

CMake 編譯靜態庫和動態庫


本帖子適用於初學者,StepByStep的入門CMake,CMake也是一門程式語言,只不過是針對編譯和連結這種程式構建的過程的語言,學習基本語法就可以初步入門,後面需要什麼複雜的功能,進階掌握需要自己去查詢官方文件,後續會給出查閱的一些方式

軟體平臺

  • Win 7
  • VMware Workstation 12 Pro
  • Ubuntu 15.10
  • CMake 3.2.2

case 4

目錄結構

+
| 
+--- CMakeLists.txt
/--+ src/
   |
   +--- CMakeLists.txt
   /--+ hellolib/
      |
      +
--- CMakeLists.txt /--+ include/ | +--- hello.h /--+ src/ | +--- hello.cpp | /--+ build/ | /--+ lib/ | +--- libhello.so
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

檔案內容

//   /CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(src)
  • 1
  • 2
  • 3
  • 4
//  /src/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
ADD_SUBDIRECTORY(hellolib)
  • 1
  • 2
  • 3
  • 4
//  /src/hellolib/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib")
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/hellolib/src HELLOlib_src)
INCLUDE_DIRECTORIES
("${PROJECT_SOURCE_DIR}/src/hellolib/include") ADD_LIBRARY(hello SHARED ${HELLOlib_src})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
//  /src/hellolib/include/hello.h
# ifndef HELLO_H
# define HELLO_H
# include <iostream>
void HelloFunc();
# endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
//  /src/hellolib/src/hello.cpp
# include "hello.h"

using namespace std;

void HelloFunc(){
    cout<<"Hello My Linux !"<<endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

語法解釋

ADD_LIBRARY(hello SHARED ${HELLOlib_src})
新增編譯庫命令:
SHARED,動態庫,libhello.so
STATIC,靜態庫,libhello.a

SET(LIBRARY_OUTPUT_PATH “${PROJECT_BINARY_DIR}/lib”)
ELIBRARY_OUTPUT_PATH是cmake預設變數,修改它可以把庫檔案的路徑修改,本例子中修改為build/lib

case 5

目錄結構

+
| 
+--- CMakeLists.txt
/--+ src/
   |
   +--- CMakeLists.txt
   /--+ hellolib/
      |
      +--- CMakeLists.txt  
      /--+ include/
         |
         +--- hello.h 
      /--+ src/
         |
         +--- hello.cpp      
|
/--+ build/
   |
   /--+ lib/
      |
      +--- libhello.so
      +--- libhello.a
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

檔案內容

//  /src/hellolib/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib")
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/hellolib/src HELLOlib_src)
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/src/hellolib/include")
ADD_LIBRARY(hello SHARED ${HELLOlib_src})
ADD_LIBRARY(hello_static STATIC ${HELLOlib_src})
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

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

#SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

其餘同case4

語法解釋

INCLUDE_DIRECTORIES(“${PROJECT_SOURCE_DIR}/src/hellolib/include”)
標頭檔案目錄包含指令

SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME “hello”)
一般我們希望同時編譯出靜態庫和動態庫,並且命名一致,但是cmake的target不允許重名,所以我們把靜態庫命名為hello_static,然後通過上述語句修改其輸出的名字,為hello,這樣就可以在lib目錄下生成libhello.a和lobhello.so。

SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
如果執行make後只生成了一種庫,說明生成第二個庫的時候刪除了同名的其他庫。上面的語句可以顯示指定不刪除同名的庫。

SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
一般動態庫會包含一個版本號,使用上述命令可以攜帶版本號:VERSION代表同太苦版本,SOVERSION指代API版本。

case 6

目錄結構

+
| 
+--- CMakeLists.txt
/--+ src/
   |
   +--- CMakeLists.txt
   /--+ hellolib/
      |
      +--- CMakeLists.txt  
      /--+ include/
         |
         +--- hello.h 
      /--+ src/
         |
         +--- hello.cpp
   /--+ mycmake/
      |
      +--- CMakeLists.txt 
      /--+ src/
         |
         +--- mycmake.cpp 
|
/--+ build/
   |
   /--+ lib/
      |
      +--- libhello.so
      +--- libhello.a
   /--+ bin/
      |
      +--- mycmake
  • 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

檔案內容

//  /src/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
ADD_SUBDIRECTORY(hellolib)
ADD_SUBDIRECTORY(mycmake)
  • 1
  • 2
  • 3
  • 4
  • 5
//  /src/mycmake/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin")
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/mycmake/src mycmake_src)
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/src/hellolib/include")
LINK_DIRECTORIES("${PROJECT_BINARY_DIR}/lib")
ADD_EXECUTABLE(mycmake ${mycmake_src})
TARGET_LINK_LIBRARIES(mycmake libhello.a)
#TARGET_LINK_LIBRARIES(mycmake libhello.so)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

其餘同case5

語法解釋

LINK_DIRECTORIES(“${PROJECT_BINARY_DIR}/lib”)
庫檔案目錄包含指令

TARGET_LINK_LIBRARIES(mycmake libhello.a)
連結指令,連結自己編譯出的靜態/動態庫,或者連結網上下載的外部庫