logo头像

技术引领生活!

cmake创建Qt工程

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
# CMakeLists.txt
cmake_minimum_required(VERSION 3.5...3.16)

project(myApp VERSION 1.0 LANGUAGES CXX)


set(CMAKE_CXX_STANDARD 11)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON) # 自动包含当前目录



find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

# 源文件
set(SOURCES
main.cpp
mainwindow.cpp
)

set(HEADERS
mainwindow.h
)

set(FORMS
mainwindow.ui
)

set(RESOURCES
resources.qrc
# 其他资源文件
)

##全局 添加 include 路径
# include_directories(
# "path/to/include"
# "another/path/to/include"
# )
## 设置变量(可选)
#set(OPENCV_INCLUDE_DIR "D:/opencv/build/include")
## 为特定目标添加包含路径
#target_include_directories(${PROJECT_NAME} PRIVATE ${OPENCV_INCLUDE_DIR})

##全局添加 lib 路径
#link_directories("path/to/lib")
## 设置变量(可选)
#set(OPENCV_LIB_DIR "D:/opencv/build/x64/vc14/lib")
## 为特定目标添加链接路径
#target_link_directories(${PROJECT_NAME} PRIVATE ${OPENCV_LIB_DIR})

# 生成可执行文件
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${FORMS} ${RESOURCES})

# 链接 Qt 库
target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)


#cmake -DCMAKE_C_FLAGS="-I/D:/opencv/build/include" -DCMAKE_CXX_FLAGS="-I/D:/opencv/build/include -L/D:/opencv/build/x64/vc14/lib" ..

源文件 main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <QApplication>
#include <QWidget>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

// Create a new instance of the main window
QWidget w;

// Show the main window
w.show();

// Run the application's event loop
return a.exec();
}

CMake 编译

这里是重点,要使用 Qt 的qtenv2.bat设置环境变量, 不然就要弄一堆 -DQt5_DIR=xxx -DQt6_DIR=xxx 之类的参数,很麻烦.

1
cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_PREFIX_PATH="E:/programes/Qt/QtLegacy/5.7/mingw53_32" -DCMAKE_C_COMPILER="E:/programes/Qt/QtLegacy/Tools/mingw530_32/bin/gcc.exe" -DCMAKE_CXX_COMPILER="E:/programes/Qt/QtLegacy/Tools/mingw530_32/bin/g++.exe"
1
cmake -S . -B build  -A win32 -DCMAKE_PREFIX_PATH="E:/programes/Qt/Qt/5.15.2/msvc2019"
1
2
3
C:\Windows\System32\cmd.exe /A /Q /K E:\programes\Qt\Qt\6.10.1\mingw_64\bin\qtenv2.bat
cmake -S . -B build/release -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build build/release

真实案例

  • 顶级目录 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
cmake_minimum_required(VERSION 3.10)

project(windLaserRadarReplica VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# MSVC UTF-8 设置提前到最前面
if(MSVC)
add_compile_options(/utf-8)
endif()

###########################################################################################
option(USE_DYNAMIC_WLP1 "使用动态加载WLP1LIB(设为OFF则使用静态链接)" ON)



# 设置自动处理 Qt 元对象系统
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# 统一查找 Qt 包(只在父目录查找一次,提高效率)
find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Widgets SerialPort Network Charts)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets SerialPort Network Charts)






# 获取编译器类型
if(MSVC)
set(COMPILER_TYPE "msvc")
elseif(MINGW)
set(COMPILER_TYPE "mingw")
else()
set(COMPILER_TYPE "other")
endif()

# 设置输出目录
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/../bin)
# 判断是顶层项目还是子项目
if(PROJECT_IS_TOP_LEVEL)
# 顶层项目:构建到上级目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
${CMAKE_BINARY_DIR}/../bin_qt${QT_VERSION_MAJOR}${QT_VERSION_MINOR}_${COMPILER_TYPE})
else()
# 子项目:构建到构建目录内
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
${CMAKE_BINARY_DIR}/bin_qt${QT_VERSION_MAJOR}${QT_VERSION_MINOR}_${COMPILER_TYPE})
endif()




if(USE_DYNAMIC_WLP1)
add_compile_definitions(USE_DYNAMIC_WLP1)
endif()

# 设置全局包含路径
include_directories(${CMAKE_SOURCE_DIR})


# 包含子目录
add_subdirectory(thirdparty/serialdev)
add_subdirectory(thirdparty/startup)
add_subdirectory(thirdparty/wplradar)
add_subdirectory(thirdparty/breakpad)


set(HEADERS
mainwidget.h
maincontroler.h
singleapplication.h
settingdialog.h
globalpara.h
globalsettings.h
workflowcontroler.h
windchartwidget.h
)

set(SOURCES
main.cpp
singleapplication.cpp
mainwidget.cpp
maincontroler.cpp
settingdialog.cpp
globalpara.cpp
globalsettings.cpp
workflowcontroler.cpp
windchartwidget.cpp
)

set(FORMS
mainwidget.ui
settingdialog.ui
)

set(RESS
res.qrc
)

# 关键修改:使用 WIN32 标志创建窗口应用程序
if(WIN32)
add_executable(${PROJECT_NAME} WIN32
${HEADERS}
${SOURCES}
${FORMS}
${RESS}
)
else()
add_executable(${PROJECT_NAME}
${HEADERS}
${SOURCES}
${FORMS}
${RESS}
)
endif()

# 链接库
target_link_libraries(${PROJECT_NAME} PRIVATE
SerialDev
AutoStartUp
WlpRadar
Breakpad
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::SerialPort
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Charts
)

# 根据平台添加特定文件
if(WIN32)
target_sources(${PROJECT_NAME} PRIVATE
res/main.rc
)
endif()

# 复制DLL文件
set(WLP1_DLL_PATH "${CMAKE_SOURCE_DIR}/thirdparty/wplradar/libs/WLP1LIB.dll")

if(EXISTS ${WLP1_DLL_PATH})
message(STATUS "配置WLP1LIB.dll复制: ${WLP1_DLL_PATH}")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${WLP1_DLL_PATH}"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/WLP1LIB.dll"
COMMENT "复制WLP1LIB.dll到可执行目录"
)
else()
message(WARNING "WLP1LIB.dll未找到: ${WLP1_DLL_PATH}")
endif()


# if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
# # 在Release模式中仍然包含调试信息
# if(MSVC)
# # MSVC的调试信息选项
# add_compile_options($<$<CONFIG:Release>:/Zi>)
# add_compile_options($<$<CONFIG:RelWithDebInfo>:/Zi>)
# else()
# # GCC/Clang的调试信息选项
# add_compile_options($<$<CONFIG:Release>:-g>)
# add_compile_options($<$<CONFIG:RelWithDebInfo>:-g>)
# endif()
# endif()

  • 子目录serialdev/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
# 创建库目标(关键修复:必须先定义目标才能链接)

set(SERIAL_TARGET_NAME SerialDev)



set(HEADERS
datetimesetter.h
gnssdata.h
serialbase.h
serialgpsinfo.h
serialnanjinlaser.h
serialsensorreader.h
serialcompassreader.h
)



set(SOURCES
serialbase.cpp
serialgpsinfo.cpp
serialnanjinlaser.cpp
datetimesetter.cpp
serialsensorreader.cpp
serialcompassreader.cpp
)

add_library(${SERIAL_TARGET_NAME} STATIC
${SOURCES}
${HEADERS}
)



find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS SerialPort)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS SerialPort)


# 为目标设置属性
target_include_directories(${SERIAL_TARGET_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>

)

# 链接 Qt SerialPort
target_link_libraries(${SERIAL_TARGET_NAME} PUBLIC
Qt${QT_VERSION_MAJOR}::SerialPort
)

# 如果 serialbase 需要 MOC 处理(有 Q_OBJECT 宏),确保继承父目录设置
set_target_properties(${SERIAL_TARGET_NAME} PROPERTIES
AUTOMOC ON
)

支付宝打赏 微信打赏

您的支持是我前行的动力!