CMake使用入門
一、開胃菜
hello目錄下的文件結構:
1234 | ├── CMakeLists.txt ├── hello.c ├── hello.h └── main.c |
C代碼見下節。
最簡單的cmake配置文件:
123 | project(HELLO) set(SRC_LIST main.c hello.c) add_executable(hello ${SRC_LIST}) |
如果要編譯成gdb可調試的debug版本,則在配置文件中加入:
1 | set(CMAKE_BUILD_TYPE Debug) |
如果要編譯成可用gprof分析的版本,則在配置文件中加入:
12 | set(CMAKE_BUILD_TYPE Profile) set(CMAKE_CXX_FLAGS_PROFILE "-pg" ) |
最簡單的編譯過程(在hello目錄中編譯):
12 | cmake . make |
這樣就會在hello目錄中生成可執行文件hello和其他cmake相關的配置文件。
為了讓代碼整潔,可以使用所謂的out-of-source編譯方式:
1234 | mkdir build cd build cmake .. make |
這樣編譯產生的所有文件都在build中了。
二、一個小工程hello示範
本例主要包含獨立庫文件、可執行文件的編譯和安裝過程中涉及的相關問題。
hello目錄中的文件結構:
12345678 | ├── CMakeLists.txt ├── libhello │ ├── CMakeLists.txt │ ├── hello.c │ └── hello.h └── src
├── CMakeLists.txt
└── main.c |
文件內容如下:
12345 | project(HELLO) cmake_minimum_required(VERSION 2.8) set(CMAKE_INSTALL_PREFIX /tmp/hello) add_subdirectory(libhello) add_subdirectory(src) |
set(CMAKE_INSTALL_PREFIX:設置程序的安裝目錄,優先順序比cmake命令參數設置高。
12345678910 | set(LIB_SRC hello.c) add_definitions( "-DLIBHELLO_BUILD" ) set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) add_library(libhello SHARED ${LIB_SRC}) add_library(hello_static STATIC ${LIB_SRC}) install(TARGETS libhello LIBRARY DESTINATION lib) install(TARGETS hello_static ARCHIVE DESTINATION lib) install(FILES hello.h DESTINATION include) set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello" ) set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello" ) |
(1)add_library:生成庫文件,SHARED表示動態鏈接庫; (2)set(LIBRARY_OUTPUT_PATH:生成的庫文件路徑,PROJECT_BINARY_DIR和CMAKE_BINARY_DIR、<projectname>_BINARY_DIR都是指進行編譯的目錄; (3)install:安裝頭文件和庫文件到相應的目錄; (4)set_target_properties(libhello:生成的庫文件名為libhello.so,若沒有這一行,庫文件名就是liblibhello.so。
12345678 | include_directories(${PROJECT_SOURCE_DIR}/libhello) link_directories(${CMAKE_INSTALL_PREFIX}/lib) aux_source_directory(. APP_SRC) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) add_executable(hello ${APP_SRC}) target_link_libraries(hello libhello) install(TARGETS hello RUNTIME DESTINATION bin) set_property(TARGET hello PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) |
(1)include_directories:指定頭文件路徑; (2)link_directories:指定庫文件路徑; (3)aux_source_directory:將當前目錄(.)中的所有文件名賦值給APP_SRC; (4)set(EXECUTABLE_OUTPUT_PATH:生成的可執行文件的路徑,PROJECT_BINARY_DIR和CMAKE_BINARY_DIR、<projectname>_BINARY_DIR都是指進行編譯的目錄; (5)add_executable:生成可執行文件,PROJECT_SOURCE_DIR和CMAKE_SOURCE_DIR、<projectname>_SOURCE_DIR都是工程的頂級目錄; (6)target_link_libraries:libhello要和./libhello/CMakeLists.txt中的libhello對應; (7)install(TARGETS:安裝程序到${CMAKE_INSTALL_PREFIX}/bin目錄; (8)set_property:設定安裝的可執行文件所需的庫文件路徑,如果沒有該項設置,會出錯:cannot open shared object file: No such file or directory。
12345678910111213 | #ifndef DBZHANG_HELLO_ #define DBZHANG_HELLO_ #if defined _WIN32
#if LIBHELLO_BUILD
#define LIBHELLO_API __declspec(dllexport)
#else
#define LIBHELLO_API __declspec(dllimport)
#endif #else
#define LIBHELLO_API #endif LIBHELLO_API void hello( const char * name); #endif //DBZHANG_HELLO_ |
1234567 | #include <stdio.h> #include "hello.h" void hello( const char *name) {
printf ( "Hello %s! , name); } |
1234567 | #include "hello.h" int main( int argc, char *argv[]) {
hello( "World" );
return 0; } |
在hello目錄下編譯程序:
12345 | mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX= /tmp make make install |
(1)-DCMAKE_INSTALL_PREFIX=/tmp讓程序的安裝目錄變為/tmp/bin,默認情況CMAKE_INSTALL_PREFIX=/usr/local; (2)若在CMakeLists.txt中設置了set(CMAKE_INSTALL_PREFIX /tmp/hello),此處的設置無效。
編譯之後,hello目錄中主要文件結構:
12345678910111213141516 | ├── build │ ├── bin │ │ └── hello │ ├── lib │ │ ├── libhello.so │ │ └── libhello.a │ ├── libhello │ └── src ├── CMakeLists.txt ├── libhello │ ├── CMakeLists.txt │ ├── hello.c │ └── hello.h └── src
├── CMakeLists.txt
└── main.c |
build目錄中有4個子目錄,libhello和src目錄中是源文件對應目錄在cmake過程中生成的中間文件。
安裝後,/tmp/hello目錄內的結構:
1234567 | ├── bin │ └── hello ├── include │ └── hello.h └── lib
├── libhello.a
└── libhello.so |
參考資料: http://blog.csdn.net/dbzhang800/article/details/6314073 http://blog.csdn.net/dbzhang800/article/details/6329068 http://www.cmake.org/Wiki/CMake_RPATH_handling Cmake實踐(by Cjacker)
推薦閱讀:
※macOS Sierra10.12.6下安裝OpenCV3.3.0
※vs2017怎麼用內置CMAKE編譯opencv??
※Ubuntu下邊用邊學CMAKE(一)
※關於OpenCV的一次Debug
※解決 Windows 下 Python 安裝 Dlib 的問題:Cmake 找不到 boost