(2021/4/23)更新模板项目供参考[helywin/cmake-modular-template]
按照如下目录结构建立好
├─assets #图片
├─build #构建目录
├─debug #debug构建后的二进制文件
├─doc #文档
├─lib #第三方库
├─release #release构建后的二进制文件
├─res #Qt的qrc文件和rc文件
└─src #源码目录
工程目录下的CMakeLists.txt
文件如下:
1cmake_minimum_required(VERSION 3.12)
2project(xxxx)
3
4add_subdirectory(src)
src
目录下CMakeLists.txt
文件如下:
1set(CMAKE_INCLUDE_CURRENT_DIR ON)
2set(CMAKE_AUTOMOC ON)
3set(CMAKE_AUTOUIC ON)
4set(CMAKE_AUTORCC ON)
5
6find_package(Qt5Core CONFIG REQUIRED)
7find_package(Qt5Widgets CONFIG REQUIRED)
8find_package(Qt5Gui CONFIG REQUIRED)
9find_package(Qt5OpenGL CONFIG REQUIRED)
10#find_package(Qt5PrintSupport CONFIG REQUIRED)
11#find_package(Qt5TextToSpeech CONFIG REQUIRED)
12set(CMAKE_CXX_COMPILER g++)
13set(CMAKE_C_COMPILER gcc)
14set(DEFINES "-DUNICODE -D_UNICODE -DWIN32 -DQT_DEPRECATED_WARNINGS")
15set(CMAKE_C_FLAGS "-fno-keep-inline-dllexport -fopenmp -march=i686 -mtune=core2 -Wa,-mbig-obj -O2 -Wall -W -Wextra ${DEFINES}")
16set(CMAKE_CXX_FLAGS "-fno-keep-inline-dllexport -fopenmp -O2 -g -Wall -W -Wextra -fexceptions -mthreads ${DEFINES}")
17
18if (CMAKE_BUILD_TYPE MATCHES Release)
19 message("release compile!!")
20 set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-Wl,-s -Wl,-subsystem,windows -mthreads")
21 add_definitions(-DQT_NO_DEBUG)
22 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/release)
23endif (CMAKE_BUILD_TYPE MATCHES Release)
24
25if (CMAKE_BUILD_TYPE MATCHES Debug)
26 message("debug compile!!")
27 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-mthreads")
28 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/debug)
29endif (CMAKE_BUILD_TYPE MATCHES Debug)
30
31aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
32include_directories(${PROJECT_SOURCE_DIR}/src)
33
34#set(UI ${PROJECT_SOURCE_DIR}/res/ui.qrc)
35
36add_executable(${PROJECT_NAME} ${SRC})
37
38target_link_libraries(${PROJECT_NAME}
39 Qt5Core
40 Qt5Widgets
41 Qt5Gui
42 Qt5OpenGL)
具体作用不解释,可以参考CMake手册和Qt手册关于CMake的部分
2019/4/21 补充:
-
可以通过CMAKE_OS_NAME来判断用来编译的是什么环境
-
从Qt官网下载的安装包CMake会找不到库的路径,可以添加以下一句解决
1set(CMAKE_PREFIX_PATH qt-path/gcc_64)
其中qt-path为qt库的路径
-
链接时把库名改为如下方式可以减少include目录的复杂程度
1target_link_libraries(${PROJECT_NAME} 2 Qt5::Core 3 Qt5::Widgets 4 Qt5::Gui 5 Qt5::OpenGL)
2019/4/28 补充
- CMake可以 执行shell命令并且获取输出和返回值
1find_program(GIT git)
2
3if ("${GIT}" STREQUAL "GIT-NOTFOUND")
4 message(WARNING "找不到git程序,无法更新git提交记录")
5 set(VERSION_REVISION "找不到提交号")
6 set(VERSION_BRANCH "找不到提交分支")
7else ()
8 unset(GIT_VERSION_NUM CACHE)
9 unset(GIT_BRANCH CACHE)
10 message("找到git,读取分支信息")
11 execute_process(
12 COMMAND git log -1 --format=%H
13 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
14 OUTPUT_VARIABLE GIT_COMMIT
15 OUTPUT_STRIP_TRAILING_WHITESPACE
16 RESULT_VARIABLE GIT_COMMIT_RESULT
17 )
18 if (NOT GIT_COMMIT_RESULT EQUAL 0)
19 message(FATAL_ERROR "找不到git提交的id号")
20 else ()
21 message("提交号 ${GIT_COMMIT}")
22 endif ()
23
24 execute_process(
25 COMMAND git symbolic-ref --short HEAD
26 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
27 OUTPUT_VARIABLE GIT_BRANCH
28 OUTPUT_STRIP_TRAILING_WHITESPACE
29 RESULT_VARIABLE GIT_BRANCH_RESULT
30 )
31 if (NOT GIT_BRANCH_RESULT EQUAL 0)
32 message(FATAL_ERROR "找不到git当前分支名称")
33 else ()
34 message("分支名称 ${GIT_BRANCH}")
35 endif ()
36
37 execute_process(
38 # COMMAND env LC_ALL=C date "+%Y-%m-%d %H:%M:%S %Z"
39 COMMAND env LC_ALL=C date "+%m %b %Y %H:%M:%S %Z"
40 OUTPUT_VARIABLE DATE
41 OUTPUT_STRIP_TRAILING_WHITESPACE
42 RESULT_VARIABLE DATE_RESULT
43 )
44 if (NOT DATE_RESULT EQUAL 0)
45 message(FATAL_ERROR "无法读取当前时间")
46 else ()
47 message("编译时间 ${DATE}")
48 endif ()
49
50 set(VERSION_COMMIT ${GIT_COMMIT})
51 set(VERSION_BRANCH ${GIT_BRANCH})
52 set(VERSION_BUILD_DATE ${DATE})
53endif ()
- CMake可以替换模板文件生成源码
模板文件如下
1#ifndef VERSION_HPP
2#define VERSION_HPP
3
4// 编译版本信息
5#define VERSION_MAJOR @VERSION_MAJOR@
6#define VERSION_MINOR @VERSION_MINOR@
7#define VERSION_MICRO @VERSION_MICRO@
8#define VERSION_COMMIT "@VERSION_COMMIT@"
9#define VERSION_BRANCH "@VERSION_BRANCH@"
10#define VERSION_BUILD_DATE "@VERSION_BUILD_DATE@"
11#define VERSION_QT "@VERSION_QT@"
12#define VERSION_QT_PLATFORM "@VERSION_QT_PLATFORM@"
13
14#endif //VERSION_HPP
在CMake里面相应设置值
1set(VERSION_QT ${QT_VERSION})
2set(VERSION_QT_PLATFORM ${QT_PLATFORM})
左边是文件里面的 @@中间的名称,右边是CMake变量,然后编写替换的文件名称就可以 了
1configure_file(src/Version.hpp.in src/Version.hpp @ONLY)
下次执行CMake会自动在编译目录下生成.hpp文件,所以还要加上include目录才能包含头文件
1include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
2019/9/9 补充
- CMake获取时间跨平台方法
原来的方式获取时间Windows上就会有问题,如下命令代替即可
1string(TIMESTAMP DATE "%m %b %Y %H:%M:%S")
时间信息就存储在DATE
里面了
参考连接:https://cmake.org/cmake/help/v3.5/command/string.html#timestamp
- CMake调用pkg-config
由于有些库不能通过CMake的find_package
查找,但是可以通过pkg-config定位,比如breakpad
包的名称可以通过pkg-config --list-all
查找
1include(FindPkgConfig)
2pkg_check_modules(BREAKPAD_CLIENT REQUIRED breakpad-client)
3if (${BREAKPAD_CLIENT_FOUND})
4 MESSAGE(STATUS "找到breakpad-client库: ${BREAKPAD_CLIENT_INCLUDE_DIRS}")
5endif()
6include_directories(${BREAKPAD_CLIENT_INCLUDE_DIRS})
7target_link_libraries(${PROJECT_NAME} ${BREAKPAD_CLIENT_LIBRARIES})
2020/2/19 补充
- 增加msvc编译参数,增加release模式生成pdb文件
1if (CMAKE_BUILD_TYPE MATCHES Debug)
2 message("Debug编译")
3 set(PROJECT_BINARY_DIR ${PROJECT_SOURCE_DIR}/debug)
4 add_definitions(-DDEBUG) # 加此宏是为了激活代码里面有的#ifdef DEBUG宏
5else () #CMAKE_BUILD_TYPE MATCHES Release
6 message("Release编译")
7 set(PROJECT_BINARY_DIR ${PROJECT_SOURCE_DIR}/release)
8 # 屏蔽Qt警告和调试
9 add_definitions(-DQT_NO_DEBUG)
10 add_definitions(-DQT_NO_DEBUG_OUTPUT)
11 add_definitions(-DQT_DEPRECATED_WARNINGS)
12 set(SUBSYSTEM_TYPE "WIN32")
13endif ()
14
15set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
16
17# 设置编译参数
18if (UNIX)
19 set(DEFINES "-Wunused-parameter")
20 set(CMAKE_CXX_FLAGS_DEBUG "-pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC ${DEFINES}")
21 set(CMAKE_C_FLAGS_DEBUG "-pipe -O2 -Wall -W -D_REENTRANT -fPIC ${DEFINES}")
22 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-fno-pie")
23
24 set(CMAKE_CXX_FLAGS_RELEASE "-pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC ${DEFINES}")
25 set(CMAKE_C_FLAGS_RELEASE "-pipe -O2 -Wall -W -D_REENTRANT -fPIC ${DEFINES}")
26 set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-fno-pie")
27elseif (WIN32)
28 if (MSVC)
29 set(DEFINES_DEBUG "-D_WINDOWS -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 /wd4100")
30 set(CMAKE_CXX_FLAGS_DEBUG "/utf-8 /sdl /EHsc -nologo -Zc:wchar_t -FS -Zc:strictStrings -Zi -MDd -W3 -w44456 -w44457 -w44458 ${DEFINES_DEBUG}")
31 set(CMAKE_C_FLAGS_DEBUG "/utf-8 /sdl -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus /FS -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc ${DEFINES_DEBUG}")
32 set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /DEBUG")
33 # set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
34
35 # release模式下生成pdb用于调试
36 set(DEFINES_RELEASE "-D_WINDOWS -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG")
37 set(CMAKE_C_FLAGS_RELEASE "/utf-8 /sdl -nologo -Zc:wchar_t -FS -Zi -Zc:strictStrings -O2 -MD -W3 -w44456 -w44457 -w44458 ${DEFINES_RELEASE}")
38 set(CMAKE_CXX_FLAGS_RELEASE "/utf-8 /sdl -nologo -Zc:wchar_t -FS -Zi -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc ${DEFINES_RELEASE}")
39 set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /DEBUG /OPT:REF /OPT:ICF")# /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:LIBC
40 else ()
41 message(FATAL_ERROR 不支持其他平台)
42 endif ()
43endif ()
其中CMAKE_CXX_FLAGS_RELEASE
的-Zi
和CMAKE_EXE_LINKER_FLAGS_RELEASE
的/DEBUG /OPT:REF /OPT:ICF
是生成pdb添加的
参考链接:
参考链接:https://cmake.org/cmake/help/v3.5/module/FindPkgConfig.html?#module:FindPkgConfig
总参考链接: