完整样例
一份CMakeLists.txt完整的样例和解释说明
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 cmake_minimum_required(VERSION 3.13) project(ust_demo CXX C) message(STATUS PROJECT_NAME=${PROJECT_NAME}) message(STATUS CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}) message(STATUS CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}) message(STATUS PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}) IF (CMAKE_BUILD_TYPE MATCHES "Debug" OR CMAKE_BUILD_TYPE MATCHES "DEBUG" ) set(CMAKE_BUILD_TYPE "Debug" ) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/out/Debug) file(MAKE_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) ELSE () set(CMAKE_BUILD_TYPE "Release" ) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/out/Release) file(MAKE_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) ENDIF () set(LIBRARY_OUTPUT_PATH ${EXECUTABLE_OUTPUT_PATH}/libs) file(MAKE_DIRECTORY ${LIBRARY_OUTPUT_PATH}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" ) set(CMAKE_C_FLAGS_DEBUG " -std=c99 -g -ggdb -O0 -Wall -Wno-unused-function -fpic -fPIC -D_DEBUG" ) set(CMAKE_CXX_FLAGS_DEBUG " -std=c++17 -g -ggdb -O0 -Wall -Wno-unused-function -fpic -fPIC -D_DEBUG" ) set(CMAKE_C_FLAGS_RELEASE " -std=c99 -O3 -Wall -Wno-unused-function -Wno-unused-result -Wno-unknown-pragmas -Wno-format-security -fpic -fPIC" ) set(CMAKE_CXX_FLAGS_RELEASE " -std=c++17 -O3 -Wall -Wno-unused-function -Wno-unused-result -Wno-unknown-pragmas -Wno-format-security -fpic -fPIC" ) set(INCLUDE_DIR ./include ) include_directories(${INCLUDE_DIR}) set(LIB_DIR lib/linux.x64) link_directories(${LIB_DIR}) aux_source_directory(./src SRC_LIST) add_executable(${PROJECT_NAME} ${SRC_LIST} ) set(LIB_LIST libHSSecuTradeApi.so t2sdk ) file(COPY ${LIB_DIR}/libHSSecuTradeApi.so DESTINATION ${LIBRARY_OUTPUT_PATH}) file(COPY ${LIB_DIR}/libt2sdk.so DESTINATION ${LIBRARY_OUTPUT_PATH}) target_link_libraries(${PROJECT_NAME} ${LIB_LIST} pthread -Wl,-rpath,'$ORIGIN'/libs ) target_include_directories(${PROJECT_NAME} PUBLIC include ../include ) target_link_directories(${PROJECT_NAME} PUBLIC ${LIB_DIR})
简洁模板
简洁版,可以基于这个改写
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 cmake_minimum_required(VERSION 3.10) project(demo CXX C) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" ) set(CMAKE_C_FLAGS_DEBUG " -std=c99 -g -ggdb -O0 -Wall -Wno-unused-function -fpic -fPIC -D_DEBUG" ) set(CMAKE_CXX_FLAGS_DEBUG " -std=c++17 -g -ggdb -O0 -Wall -Wno-unused-function -fpic -fPIC -D_DEBUG" ) set(CMAKE_C_FLAGS_RELEASE " -std=c99 -O3 -Wall -Wno-unused-function -fpic -fPIC" ) set(CMAKE_CXX_FLAGS_RELEASE " -std=c++17 -O3 -Wall -Wno-unused-function -fpic -fPIC" ) include_directories( include ) link_directories( lib ) aux_source_directory(src SRC_LIST) add_executable(${PROJECT_NAME} ${SRC_LIST} ) target_link_libraries(${PROJECT_NAME} pthread )
使用方式
用cmake
命令生成Makefile
时会生成一些中间文件和一些缓存文件,我一般会在根CMakefile.txt的同级目录下新建build目录用来构建,通常的步骤是
1 2 3 4 mkdir build cd build cmake .. make
用cmake
生成Makefile
时是增量处理的,如果想重新生成,需要先删除CMakeCache.txt
make clean
可以清除目标文件以保证再次make
时是重新生成的。
在Windows上如果生成想用minGW的Makefile需要使用-G"Unix Makefiles"
参数,即
1 2 cmake -G"Unix Makefiles" .. make
记得用minGW/bin/mingw32-make.exe
复制一份make.exe
,并把minGW/bin
添加到PATH
构建后自动复制文件
有时候我们想将依赖的头文件(构建.so时需要依赖)或库文件复制到指定路径
可以使用如下命令
1 2 3 4 5 add_custom_command (TARGET <项目名> POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory <源路径> <目标路径> )
1 2 3 4 5 6 7 8 9 file (GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h" )foreach (HEADER_FILE ${HEADER_FILES} ) add_custom_command (TARGET amaquote POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${HEADER_FILE} ${OUTPUT_PATH} /include ) endforeach ()
执行Shell命令并保存输出结果到变量中
1 2 3 4 5 EXECUTE_PROCESS (COMMAND <Shell命令> TIMEOUT 5 OUTPUT_VARIABLE <变量名> OUTPUT_STRIP_TRAILING_WHITESPACE )
样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 EXECUTE_PROCESS (COMMAND sh ${CMAKE_SOURCE_DIR} /is_abi_gcc4.sh TIMEOUT 5 OUTPUT_VARIABLE IS_ABI_GCC4 OUTPUT_STRIP_TRAILING_WHITESPACE ) IF (IS_ABI_GCC4 STREQUAL "1" ) message (STATUS "Use gcc4-compatible libs" ) SET (ABI_VERSION gcc4-compatible) SET (LIB_DIR utils/lib/linux.x64/abi-gcc4-compatible) ELSE () message (STATUS "Use cxx11 libs" ) SET (ABI_VERSION cxx11) SET (LIB_DIR utils/lib/linux.x64/abi-cxx11) ENDIF ()
写在COMMAND
后面的命令支持带参数但不支持管道,如果需要用到管道可以写在外部的.sh中再进行调用
1 2 g++ -v -x 2>&1|grep gcc4-compatible|wc -l