CMake Practice.pdflinux
. ├── CMakeLists.txt └── main.cpp
#include <iostream> int main() { std::cout <<"Hello World" << std::endl; return 0; }
PROJECT (PRACTISE1) SET(SRC_LIST main.cpp) MESSAGE(STATUS "This is BINARY dir "${PRACTISE1_BINARY_DIR}) MESSAGE(STATUS "This is BINARY dir "${PROJECT_BINARY_DIR}) MESSAGE(STATUS "This is SOURCE dir "${PRACTISE1_SOURCE_DIR}) MESSAGE(STATUS "This is SOURCE dir "${PROJECT_SOURCE_DIR}) ADD_EXECUTABLE(practise1 ${SRC_LIST})
$ cmake .
... -- This is BINARY dir xxx/practise1 -- This is BINARY dir xxx/practise1 -- This is SOURCE dir xxx/practise1 -- This is SOURCE dir xxx/practise1 ...
make clean
. ├── bin ├── build ├── CMakeLists.txt └── src ├── CMakeLists.txt └── main.cpp
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin ADD_EXECUTABLE(practise2 main.cpp)
PROJECT(PRACTISE2) MESSAGE(STATUS "PROJECT_BINARY_DIR= "${PROJECT_BINARY_DIR}) MESSAGE(STATUS "PROJECT_SOURCE_DIR= "${PROJECT_SOURCE_DIR}) ADD_SUBDIRECTORY(src)
$ cd build $ cmake .. $ make
-- PROJECT_BINARY_DIR= xxx/practise2/build -- PROJECT_SOURCE_DIR= xxx/practise2
practise2最后生成在bin目录中ios
ADD_LIBRARY(库名 SHARED 源文件列表)
把上面的ADD_EXECUTABLE修改成ADD_LIBRARY就能够生成库文件了, 第二个参数SHARED表示生成动态库,STATIC表示生成静态库shell
SET(LIBRARY_OUTPUT_PATH <路径>)
ADD_LIBRARY(hello_static STATIC hello.c) SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
本来会输出 libhello_static.a
,加上后面这个后,库文件名变为libhello.a
windows
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION 指代动态库版本,SOVERSION 指代 API 版本。函数
SET(LIBHELLO_SRC hello.cpp) SET(LIBRARY_OUTPUT_PATH lib) #目标文件生成目录设置为lib ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) ADD_LIBRARY(hello_static STATIC ${LIBHELLO_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) #不清理上个版本的生成文件
make以后会同时生成两个文件ui
├── lib │ ├── libhello.a │ └── libhello.so
因为windows调用dll通常是须要dll文件,带有symbol的lib文件,以及函数声明的头文件,所以须要作额外的配置,CMAKE在动态库编译的以前会预约义一个宏 {库名}_EXPORTS
,判断这个宏来决定dll中的函数是否是导出函数,有了导出函数vs才会额外的生成lib文件。debug
如下代码兼容windows和linux dynamic.h日志
#ifndef __DYNAMIC_H_ #define __DYNAMIC_H_ #ifdef _WIN32 #ifdef dynamic_EXPORTS #define __DLL_API __declspec(dllexport) #else #define __DLL_API __declspec(dllimport) #endif #endif //_WINDOWS #ifdef __linux__ #ifdef dynamic_EXPORTS #define __DLL_API __attribute__((visibility("default"))) #else #define __DLL_API #endif #endif //__linux__ __DLL_API void fun_dynamic(); #endif
dynamic_EXPORTS这个宏是cmake自动根据库名生成的,正好能够用来做为是导出函数的判断code
dynamic.cppci
#include "dynamic.h" #include <iostream> __DLL_API void fun_dynamic() { std::cout << "msg from dynamic" << std::endl; }
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
这条指令能够用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,若是路径 中包含了空格,可使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的 后面,你能够经过两种方式来进行控制搜索路径添加的方式: 1,CMAKE_INCLUDE_DIRECTORIES_BEFORE,经过 SET 这个 cmake 变量为 on,能够 将添加的头文件搜索路径放在已有路径的前面。 2,经过 AFTER 或者 BEFORE 参数,也能够控制是追加仍是置前。
添加非标准的共享库搜索路径
LINK_DIRECTORIES(directory1 directory2 ...)
为 target 添加须要连接的库,target能够是可执行文件,也能够是库文件
TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2 ...)
├── bin ├── build ├── CMakeLists.txt ├── libs └── src ├── CMakeLists.txt ├── libdynamic │ ├── CMakeLists.txt │ ├── dynamic.cpp │ └── dynamic.h ├── libstatic │ ├── CMakeLists.txt │ ├── static.cpp │ └── static.h └── main ├── CMakeLists.txt └── main.cpp
本工程由一个可执行文件和一个静态库和一个动态库构成,可执行文件调用了这两个库文件,可执行文件和动态库最后生成在bin目录下,静态库生成在libs目录。
PROJECT(PRACTISE3) MESSAGE(STATUS "PROJECT_BINARY_DIR= "${PROJECT_BINARY_DIR}) MESSAGE(STATUS "PROJECT_SOURCE_DIR= "${PROJECT_SOURCE_DIR}) ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(libstatic) ADD_SUBDIRECTORY(libdynamic) ADD_SUBDIRECTORY(main)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) ADD_LIBRARY(dynamic SHARED dynamic.cpp)
设定生成目录为根目录下面的bin
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/libs) ADD_LIBRARY(static STATIC static.cpp)
设定生成目录为根目录下面的libs
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/libstatic ${PROJECT_SOURCE_DIR}/src/libdynamic) SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) ADD_EXECUTABLE(practise3 main.cpp) TARGET_LINK_LIBRARIES(practise3 static) TARGET_LINK_LIBRARIES(practise3 dynamic)
设定了头文件的查找目录,并在最后指定了须要连接的动态库和静态库,库的名字应该与ADD_LIBRARY指令中使用的名字一致
Scanning dependencies of target static [ 33%] Building CXX object src/libstatic/CMakeFiles/static.dir/static.o Linking CXX static library ../../../libs/libstatic.a [ 33%] Built target static Scanning dependencies of target dynamic [ 66%] Building CXX object src/libdynamic/CMakeFiles/dynamic.dir/dynamic.o Linking CXX shared library ../../../bin/libdynamic.so [ 66%] Built target dynamic Scanning dependencies of target practise3 [100%] Building CXX object src/main/CMakeFiles/practise3.dir/main.o Linking CXX executable ../../../bin/practise3 [100%] Built target practise3
自动根据各个项目的包含关系决定构建的顺序