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.aSET(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)
連結指令,連結自己編譯出的靜態/動態庫,或者連結網上下載的外部庫