一、開胃菜
hello目錄下的文件結構:
├── CMakeLists.txt
├── hello.c
├── hello.h
└── main.c
C代碼見下節。
最簡單的cmake配置文件:
project(HELLO)
set(SRC_LIST main.c hello.c)
add_executable(hello ${SRC_LIST})
如果要編譯成gdb可調試的debug版本,則在配置文件中加入:
set(CMAKE_BUILD_TYPE Debug)
如果要編譯成可用gprof分析的版本,則在配置文件中加入:
set(CMAKE_BUILD_TYPE Profile)
set(CMAKE_CXX_FLAGS_PROFILE "-pg")
最簡單的編譯過程(在hello目錄中編譯):
cmake . make
這樣就會在hello目錄中生成可執行文件hello和其他cmake相關的配置文件。
為了讓代碼整潔,可以使用所謂的out-of-source編譯方式:
mkdir build cd build cmake .. make
這樣編譯產生的所有文件都在build中了。
二、一個小工程hello示范
本例主要包含獨立庫文件、可執行文件的編譯和安裝過程中涉及的相關問題。
hello目錄中的文件結構:
├── CMakeLists.txt
├── libhello
│?? ├── CMakeLists.txt
│?? ├── hello.c
│?? └── hello.h
└── src├── CMakeLists.txt└── main.c
文件內容如下:
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命令參數設置高。
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。
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。
#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_
#include <stdio.h>
#include "hello.h"void hello(const char *name)
{printf ("Hello %s!\n", name);
}
#include "hello.h"int main(int argc, char *argv[])
{hello("World");return 0;
}
在hello目錄下編譯程序:
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目錄中主要文件結構:
├── 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目錄內的結構:
├── 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