代码拉取完成,页面将自动刷新
有关 cmake 的构建工作
CMakeLists.txt
)。有关 qmake 的构建,
一些构建补充
有关当前相关内容模板(来自 社区维护的星火应用商店 项目)
cmake_minimum_required(VERSION 3.5.1)
project(spark-store LANGUAGES CXX VERSION 0.0.1)
# 构建 qwidgetdemo 的配置流程
include(cmake/SparkEnvConfig.cmake) # 设置一些有关QT构建的开关
include(cmake/SparkMacrosConfig.cmake) # 声明了一些 spark_ 开头的 macro 宏
include(cmake/SparkFindQt5Config.cmake) # 提供了 target_link_qt5 用于目标链接 qt5 的库
# 1.传统构建
# spark_add_executable(control-battery # 与 add_executable 相同
# control/battery/battery.cpp # 传统构建方式需要添加指定的源代码文件
# control/battery/battery.h
# control/battery/main.cpp
# ...
# )
# 2. 传统链接目标
# target_link_libraries(control-battery
# Qt5::Core Qt5::Widgets Qt5::Gui # 传统构建方式需要链接指定的库
# )
# 3. 使用 Spark 骨架构建与链接目标
# _path 表示将指定的目录作为构建,自动将目录中源代码构建为一个目标(只支持一个目录)
# spark_add_executable_path(control-battery
# control/battery
# )
# target_link_qt5(control-battery) # 构建的目标需要使用 qt5 库
# 4. 分层构建: 在下层目录中创建 CMakeLists.txt,并继续使用 Spark 骨架构建与链接目标
# add_subdirectory(control) # 传统子构建方式,但已经可使用 spark_ 宏用于构建目标
# 5. 下层目录中的 CMakeLists.txt
# cmake_minimum_required(VERSION 3.5.1)
# spark_add_executable_path(control-battery battery)
# target_link_qt5(control-battery) # 构建的目标需要使用 qt5 库
参阅内容:
本计划出处探索
control | tool | video | widget | ui | other | third |
---|---|---|---|---|---|---|
☑ battery | ☑ comtool | videobox | ☑ colorwidget | ☑ flatui | ☑ bgdemo | hotkey |
☑ devicebutton | ☑ nettool | videopanel | ☑ framelesswidget | ☑ styledemo | ☑ dbpage | shortcut |
☑ devicesizetable | ☑ netserver | videowidget | ☑ gifwidget | ☑ uidemo01 | ☑ lineeditnext | qwtdemo |
☑ imageswitch | ☑ base64helper | ☑ lunarcalendarwidget | ☑ uidemo08 | ☑ mouseline | qcustomplotdemo | |
☑ ipaddress | ☑ countcode | (win32)playffmpeg | ☑ maskwidget | ☑ uidemo09 | ☑ ntpclient | |
☑ lightbutton | ☑ emailtool | (win32)playvlc | ☑ movewidget | ☑ uidemo10 | ☑ trayicon | designer |
☑ navbutton | ☑ moneytool | (win32)plaympv | ☑ screenwidget | ☑ iconhelper | ☑ echartgauge | hotkey |
☑ savelog | ☑ pngtool | ☑ multobj2slot | ||||
☑ saveruntime | ☑ keytool | ☑ lunarcalendarwidget | hotkey | |||
☑ smoothcurve | ☑ keydemo | shortcut | ||||
☑ zhtopy | ☑ livetool | miniblink | ||||
☑ livedemo | qwtdemo |
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
control
层过程中产生了新的构建宏
# spark_add_executable_paths
# 自定义构建宏,基于指定的前缀名称,处理后续参数为子目录
# item: 为进行遍历后的单项,类似于 python3 中的 (for item in items:)
# file: 为在目录中不以递归(GLOB_RECURSE)方式寻找 qrc 文件,需要将其参与编译才能被 rcc
# 并根据 prefix-<item> 生成构建目标,
macro(spark_add_executable_paths _prefix_path)
set(PATHS ${ARGN})
foreach(item IN LISTS PATHS)
file(GLOB QRCS "${item}/*.qrc")
message(">>> add_executable: " "${_prefix_path}-${item} ${item} + ${QRCS}")
spark_add_executable_path(${_prefix_path}-${item} ${item} ${QRCS})
target_link_qt5(${_prefix_path}-${item})
endforeach(item IN LISTS PATHS)
endmacro(spark_add_executable_paths _prefix_path)
在完成构建 other
层过程中产生了新的宏,用于扩展 target_link_<name>
# spark_add_link
# 自定义宏以代替当前使用 fucntion 定义 target_link_<name> 结构
# _IN_NAME: 此宏生成 target_link_<name> 的要求参数
# ARGN: 此宏剩余的参数列表
# 在使用 target_link_<name> 时
# _NAME: 用于此 fucntion 中的要求参数: <_NAME>目标将要连接此库
macro(spark_add_link _IN_NAME)
function(target_link_${_IN_NAME} _NAME)
message("LINK ${_NAME} ${ARGN}")
target_link_libraries(${_NAME}
${ARGN})
endfunction(target_link_${_IN_NAME} _NAME)
endmacro(spark_add_link _IN_NAME)
# function(target_link_qt5 NAME)
# target_link_libraries(${NAME}
# Qt5::Core
# Qt5::Widgets
# Qt5::Network)
# endfunction(target_link_qt5 NAME)
# 使用 spark_add_link 生成 target_link_qt5 以替代上面内容
spark_add_link(qt5 Qt5::Core Qt5::Widgets Qt5::Network)
# spark_add_link_qt5
# 自定义宏 spark_add_link_qt5 以扩展 target_link_qt5_<name> 结构
# _IN_NAME: 此宏使用嵌套宏 spark_add_link 时追加 qt5_<name> 名称
# 同等于 spark_add_link(qt_<name> ${ARGN})
macro(spark_add_link_qt5 _IN_NAME)
spark_add_link(qt5_${_IN_NAME} ${ARGN})
endmacro(spark_add_link_qt5 _IN_NAME)
# 使用 spark_add_link_qt5 生成 target_link_qt5_<name> 的宏
spark_add_link_qt5(sql Qt5::Sql)
spark_add_link_qt5(concurrent Qt5::Concurrent)
spark_add_link_qt5(webenginewidgets Qt5::WebEngineWidgets)
other-dbpage
时采用了以上的生成的 target_link_qt5_sql
宏用于链接 Qt5::Sql
库widget
层过程中,详细处理了 framelesswidget
的子模块部分构建
cmake_minimum_required(VERSION 3.5.1)
# 1. 使用宏自动展开单次构建为多次构建
spark_add_executable_paths(widget
colorwidget # 子构建说明注释
framelesswidget # 此可执行目标有后续依赖处理项
gifwidget # 子构建说明注释
lunarcalendarwidget # 子构建说明注释
maskwidget # 子构建说明注释
movewidget # 子构建说明注释
screenwidget # 子构建说明注释
)
# 此处处理 framelesswidget 的各部分模块(其实这里应该再向下创建一层构建,不过算了)
# 1. 首先构建 core
spark_add_libraries_path(framelesscore framelesswidget/framelesscore)
target_link_qt5(framelesscore) # 构建的目标需要使用 qt5 库
# 2. 再构建 form
# form 依赖了 core
spark_add_libraries_path(framelessform framelesswidget/framelessform)
target_link_framelesscore(framelessform)
# 3. 可执行目标的依赖
# framelesswidget 依赖了 from 并间接依赖了 core 及 Qt5
target_link_framelessform(widget-framelesswidget)
在完成构建 tool
层过程中,详细处理了 comtool/nettool/netserver
的子模块部分构建
cmake_minimum_required(VERSION 3.5.1)
# 1. 构建第三方库
set(QExtSerialPort_SOURCES
3rd_qextserialport/qextserialport_global.h
3rd_qextserialport/qextserialport_p.h
3rd_qextserialport/qextserialport.cpp
3rd_qextserialport/qextserialport.h
)
# 根据构建系统来导致相关文件
if(CMAKE_HOST_WIN32)
list(APPEND QExtSerialPort_SOURCES 3rd_qextserialport/qextserialport_win.cpp)
elseif(CMAKE_HOST_UNIX)
list(APPEND QExtSerialPort_SOURCES 3rd_qextserialport/qextserialport_unix.cpp)
endif(CMAKE_HOST_WIN32)
spark_add_libraries(qextserialport ${QExtSerialPort_SOURCES})
target_link_qt5(qextserialport)
spark_add_libraries_path(smtpclient 3rd_smtpclient)
target_link_qt5(smtpclient)
# 2. 使用宏自动展开单次构建为多次构建
spark_add_executable_paths(tool
# comtool # 特殊结构构建
# nettool # 特殊结构构建
# netserver # 特殊结构构建
base64helper # 子构建说明注释
countcode # 子构建说明注释
emailtool # 子构建说明注释
moneytool # 子构建说明注释
pngtool # 子构建说明注释
keytool # 子构建说明注释
keydemo # 子构建说明注释
livetool # 子构建说明注释
livedemo # 子构建说明注释
)
target_link_smtpclient(tool-emailtool) # tool-emailtool 依赖了 smtpclient 库
# 3. 构建 comtool
# set(COMTOOL_INCLUDES
# comtool
# comtool/api
# comtool/form
# 3rd_qextserialport
# )
# spark_add_libraries_path(comtool_api comtool/api)
# target_link_qt5(comtool_api)
# target_include_directories(comtool_api PUBLIC ${COMTOOL_INCLUDES})
# spark_add_libraries_path(comtool_form comtool/form)
# target_link_comtool_api(comtool_form)
# target_link_qextserialport(comtool_form)
# spark_add_executable_path(tool-comtool comtool comtool/qrc/main.qrc)
# target_link_comtool_form(tool-comtool)
# 4. 构建 nettool
# set(NETTOOL_INCLUDES
# nettool
# nettool/api
# nettool/form
# 3rd_qextserialport
# )
# spark_add_libraries_path(nettool_api nettool/api)
# target_link_qt5(nettool_api)
# target_link_qt5_websockets(nettool_api)
# target_include_directories(nettool_api PUBLIC ${NETTOOL_INCLUDES})
# spark_add_libraries_path(nettool_form nettool/form)
# target_link_nettool_api(nettool_form)
# target_link_qextserialport(nettool_form)
# spark_add_executable_path(tool-nettool nettool nettool/qrc/main.qrc)
# target_link_nettool_form(tool-nettool)
# 此处发现结构类似,使用宏进行抽象构建
# add_executable_api_form_qrc
# 自定义宏用于抽象构建 comtool/nettool/netserver 这种特殊包含结构的子构建
#
macro(add_executable_api_form_qrc _dir)
spark_add_libraries_path(${_dir}_api ${_dir}/api)
target_link_qt5(${_dir}_api)
target_include_directories(${_dir}_api PUBLIC
${_dir}
${_dir}/api
${_dir}/form
3rd_qextserialport
)
spark_add_libraries_path(${_dir}_form ${_dir}/form)
# target_link_${_dir}_api(${_dir}_form) # 此处无法使用展开,将在外部处理
target_link_qextserialport(${_dir}_form)
spark_add_executable_path(tool-${_dir} ${_dir} ${_dir}/qrc/main.qrc)
# target_link_${_dir}_form(tool-${_dir}) # 此处无法使用展开,将在外部处理
endmacro(add_executable_api_form_qrc _dir)
add_executable_api_form_qrc(comtool)
target_link_comtool_api(comtool_form)
target_link_comtool_form(tool-comtool)
add_executable_api_form_qrc(nettool)
target_link_nettool_api(nettool_form)
target_link_nettool_form(tool-nettool)
target_link_qt5_websockets(nettool_api) # tool-nettool 需要依赖 QtWebSockets
add_executable_api_form_qrc(netserver)
target_link_netserver_api(netserver_form)
target_link_netserver_form(tool-netserver)
comtool/nettool/netserver
的子构建时,发现三个目标均有复杂形式的头文件包含过程,类似于循环包含(也可指循环依赖结构)。处理过程复杂,并且有三个相同构建过程,在使用宏抽象构建后减少了大量重复性构建过程。导出依赖图,可能因是头文件循环依赖原因,未在此处展现
可以,加油
在完成构建 ui
层过程中,详细处理了 uidemo<x>
的部分构建(x
为 01
,08
,09
,10
)
cmake_minimum_required(VERSION 3.5.1)
# 1. 使用宏自动展开单次构建为多次构建
spark_add_executable_paths(ui
# core_base # 非独立库或程序不构建
# core_qss # 非独立库或程序不构建
flatui # 子构建说明注释
iconhelper # 子构建说明注释
# styledemo # qrc文件多,独立构建
# uidemo01 # 复杂结构。宏构建
# uidemo08 # 复杂结构。宏构建
# uidemo09 # 复杂结构。宏构建
# uidemo10 # 复杂结构。宏构建
)
# 2. 构建 styledemo
# qrc 文件比较多
spark_add_executable_path(ui-styledemo styledemo
styledemo/qrc/font.qrc
styledemo/qrc/main.qrc
styledemo/qrc/qm.qrc
styledemo/qrc/qss.qrc
)
target_link_qt5(ui-styledemo)
# 分析构建 uidemo<x>
# 构建 uidemo<x> 复杂程度较高
# 分析过程
# uidemo<x> 使用了哪些文件(存在头文件交叉引用,第3、4点)
# 1. 使用了 core_base/qrc 下的文件
# 2. 使用了 core_qss 下的文件
# 3. core_base 下的文件引用了 uidemo<x> 下的 head.h
# 4. uidemo<x> 使用了 core_base/appinit.h
# 5. uidemo<x>/form 使用了 core_base/iconhelper.h 与 core_base/quihelper.h
# 分析结果
# 抽象出构建结构并为 uidemo<x> 使用宏构建
# 参与构建 uidemo01 的文件
set(CORE_BASE_QRCS
core_base/qrc/font.qrc
core_base/qrc/image.qrc
core_base/qrc/qm.qrc
)
set(CORE_QSS_QRCS
core_qss/qss.qrc
)
set(UIHelper_Appinit
core_base/quihelper.cpp # 被 uidemo<x>/form/frmmain.cpp 使用
core_base/quihelper.h # 被 uidemo<x>/form/frmmain.cpp 使用
core_base/appinit.cpp # 被 uidemo<x>/main.cpp 使用
core_base/appinit.h # 被 uidemo<x>/main.cpp 使用
)
set(IconHelper
iconhelper/iconhelper.cpp
iconhelper/iconhelper.h
)
# 3. 构建 uidemo01 并制作抽象结构
# 构建 uidemo1 的 form 库
# 使用了 iconhelper
spark_add_libraries_path(uidemo01_form uidemo01/form
${UIHelper_Appinit}
${IconHelper}
)
target_include_directories(uidemo01_form PUBLIC
core_base/
uidemo01/
)
target_link_qt5(uidemo01_form)
# 构建 uidemo01 可执行文件
spark_add_executable_path(ui-uidemo01 uidemo01
uidemo01/other/main.qrc
${CORE_BASE_QRCS}
${CORE_QSS_QRCS}
${UIHelper_Appinit}
${IconHelper}
)
target_link_uidemo01_form(ui-uidemo01)
# 使用宏进行抽象构建 uidemo<x> ,保留了 01 构建
macro(spark_add_uidemo_id _id)
spark_add_libraries_path(uidemo${_id}_form uidemo${_id}/form
${UIHelper_Appinit}
${IconHelper}
)
target_include_directories(uidemo${_id}_form PUBLIC
core_base/
uidemo${_id}/
)
target_link_qt5(uidemo${_id}_form)
# 构建 uidemo${_id} 可执行文件
if(NOT ${_id} STREQUAL "10")
set(uidemo${_id}_other
uidemo${_id}/other/main.qrc) # uidemo10 不存在 other 目录,但其它存在
endif(NOT ${_id} STREQUAL "10")
spark_add_executable_path(ui-uidemo${_id} uidemo${_id}
${uidemo${_id}_other} # 可能为空值的变量,uidemo10 将不存在此变量值
${CORE_BASE_QRCS}
${CORE_QSS_QRCS}
${UIHelper_Appinit}
${IconHelper}
)
# target_link_uidemo${_id}_form(ui-uidemo${_id}) # 此处无法使用展开,将在外部处理
endmacro(spark_add_uidemo_id _id)
# spark_add_uidemo_id(01) # 已构建,保留
spark_add_uidemo_id(08) # 构建 uidemo08
target_link_uidemo08_form(ui-uidemo08)
spark_add_uidemo_id(09) # 构建 uidemo09
target_link_uidemo09_form(ui-uidemo09)
spark_add_uidemo_id(10) # 构建 uidemo10
target_link_uidemo10_form(ui-uidemo10)
uidemo01/uidemo08/uidemo09/uidemo10
的子构建时,发现三个目标均有复杂形式的头文件包含过程,类似于交叉包含形式。处理过程复杂,在理清关系后,尝试构建 uidemo01
,并在成功之后使用相同结构进行抽象(为 uidemo08/uidemo09/uidemo10
进行了较为简单的构建处理)登录 后才可以发表评论