cmake 构建Qt存在多个子项目的应用

概述:一般在开发UI应用时候我们都会存在多个子项目,比如一个是主UI界面的项目,有些动态库的项目,主UI中用到子项目中的动态库,我们来看看如何利用cmake来构建这样的一个工程,方便我们在跨平台中开发(macos、windows、linux)

前提条件:安装了CMake Qt5开发环境

1、工程的项目结构

1.1 目录说明

        CCQTAPP目录 :项目的主目录

        CMakeLists.txt: 项目的主CMakeLists.txt

        cc-desktop目录: 主程序(主要是UI)

        cc-engine目录: 提供给主程序调用的动态库(主要提供一些数据获取接口或者其他逻辑)

2、项目主CMakeLists.txt

cmake_minimum_required(VERSION 3.6)

set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "My multi config types" FORCE)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER AutoMoc)

if(UNIX AND NOT APPLE)
    set(LINUX 1)
endif(UNIX AND NOT APPLE)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(CcQtApp)

if(WIN32)
	add_definitions("/wd4819")
elseif(APPLE) 
   	SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.12")
endif(WIN32)

macro(ADD_FRAMEWORK fwname appname)
find_library(FRAMEWORK_${fwname}
    NAMES ${fwname}
    PATHS ${CMAKE_OSX_SYSROOT}/System/Library
    PATH_SUFFIXES Frameworks
    NO_DEFAULT_PATH)
if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
    MESSAGE(ERROR ": Framework ${fwname} not found")
else()
    TARGET_LINK_LIBRARIES(${appname} ${FRAMEWORK_${fwname}})
    MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
endif()
endmacro(ADD_FRAMEWORK)

if(WIN32)
    set(QtVersion 5.14)
elseif(APPLE)
    set(QtVersion 5.7)
elseif(LINUX)
    set(QtVersion 5.14)
endif()

# 将项目目录组织化的宏,使用cmake的source_group函数
macro(cc_source_group_by_dir source_files)       
	set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR}/)
	foreach(sgbd_file ${${source_files}})
		string(REGEX REPLACE ${sgbd_cur_dir} "" sgbd_fpath ${sgbd_file})
		string(REGEX REPLACE "[^/\\\\]+$" "" sgbd_group_name ${sgbd_fpath})
		if(sgbd_group_name)
			string(REPLACE "/"   "\\\\"  sgbd_group_name_normal ${sgbd_group_name})
			source_group(${sgbd_group_name_normal} FILES ${sgbd_file})
		endif(sgbd_group_name)	
	endforeach(sgbd_file)
endmacro(cc_source_group_by_dir)

# 添加子项目cc-desktop
add_subdirectory(cc-desktop)

# 添加子项目cc-engine
add_subdirectory(cc-engine)

3、子项目cc-desktop

        3.1 cc-desktop的CMakeLists.txt

                

cmake_minimum_required(VERSION 3.6)

project(CcQtApp)

SET(CMAKE_PREFIX_PATH $ENV{QTDIR})

find_package(Qt5Core $ENV{QTVERSION} REQUIRED)
find_package(Qt5Concurrent $ENV{QTVERSION} REQUIRED)
find_package(Qt5Sql $ENV{QTVERSION} REQUIRED)
find_package(Qt5Gui $ENV{QTVERSION} REQUIRED)
find_package(Qt5Widgets $ENV{QTVERSION} REQUIRED)
find_package(Qt5Network $ENV{QTVERSION} REQUIRED)
find_package(Qt5Multimedia $ENV{QTVERSION} REQUIRED)

set(CMAKE_AUTOMOC ON)                    
set(CMAKE_INCLUDE_CURRENT_DIR ON)

FILE(GLOB_RECURSE FORMS "*.ui")
QT5_WRAP_UI(FORMS_UIC ${FORMS})


file(GLOB_RECURSE All_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.mm 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.m 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.mm 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.c 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.cc 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.hh 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.h 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)

cc_source_group_by_dir(All_SOURCES)	

include_directories(${Qt5Core_PRIVATE_INCLUDE_DIRS}
					${Qt5Widgets_PRIVATE_INCLUDE_DIRS}
					${CMAKE_CURRENT_SOURCE_DIR}
					${CMAKE_CURRENT_SOURCE_DIR}/../cc-engine/include
)


if(WIN32)
	set(exe_property WIN32)
	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /Zi /MP /Gm- /Qpar /wd4996")
	if(${close_optimize} STREQUAL "ON")
		set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Od")
	endif()
	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
	set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF /LARGEADDRESSAWARE")
	add_definitions(-DUNICODE -D_UNICODE -D_SCL_SECURE_NO_WARNINGS -DWIN32 -DV_LOG -DCURL_STATICLIB)

	link_directories(${CMAKE_CURRENT_BINARY_DIR}/../cc-engine/$(CONFIGURATION))	

	set(LINK_LIBRARY CcEngine.lib)

elseif(APPLE)
    SET(BUILD_WITH_INSTALL_RPATH TRUE)
    set(exe_property MACOSX_BUNDLE)
    set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}")

	message("CMAKE_OSX_DEPLOYMENT_TARGET is ${CMAKE_OSX_DEPLOYMENT_TARGET}")
	message(${CMAKE_CURRENT_BINARY_DIR})

	set(LINK_LIBRARY libCcEngine.dylib)
	link_directories(${CMAKE_CURRENT_BINARY_DIR}/../cc-engine/$(CONFIGURATION))	

elseif(LINUX)
	SET(CMAKE_BUILD_TYPE Debug)
	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif(WIN32)

set(NAME CcApp)
add_executable(${NAME} ${exe_property} ${All_SOURCES} ${FORMS_UIC} ${MACOSX_BUNDLE_ICON_FILE})

if(WIN32)
elseif(APPLE)
	ADD_FRAMEWORK(AVFoundation CcApp)
	ADD_FRAMEWORK(Foundation CcApp)
	ADD_FRAMEWORK(Security CcApp)
	ADD_FRAMEWORK(Carbon CcApp)
	ADD_FRAMEWORK(Appkit CcApp)
	ADD_FRAMEWORK(VideoDecodeAcceleration CcApp)
	ADD_FRAMEWORK(VideoToolbox CcApp)	
	ADD_FRAMEWORK(SystemConfiguration CcApp)	

	set_target_properties(CcApp PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
	set_target_properties(CcApp PROPERTIES XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS "YES")
	set_target_properties(CcApp PROPERTIES XCODE_ATTRIBUTE_SEPARATE_STRIP "YES")
	set_target_properties(CcApp PROPERTIES XCODE_ATTRIBUTE_STRIP_STYLE "Non-Global Symbols")
endif(WIN32)

if(APPLE)
	set_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "x86_64")
endif()

if(WIN32)
	qt5_use_modules(${NAME} WinExtras)
elseif(APPLE)
endif(WIN32)

qt5_use_modules(${NAME} Core)
qt5_use_modules(${NAME} Concurrent)
qt5_use_modules(${NAME} Sql)
qt5_use_modules(${NAME} Gui)
qt5_use_modules(${NAME} Widgets)
qt5_use_modules(${NAME} Network)
qt5_use_modules(${NAME} Multimedia)
qt5_use_modules(${NAME} WebEngineWidgets)
qt5_use_modules(${NAME} WebChannel)

target_link_libraries(${NAME} ${LINK_LIBRARY})

        3.2 cc-desktop的main.cpp文件

#include <QApplication>
#include <QWidget>
#include <QDebug>

//cc-engine里面生成的动态库
#include "CcDataManage.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
  
    QWidget window;
    window.resize(650, 350);
    window.setWindowTitle("简单的cmake构建的Qt窗口程序");
    window.show();
    
    CcDataManage data_manage;
    qDebug() << "Get Data From cc-engine dynamic library: " << data_manage.GetCurrentJsonData();
  
    return app.exec();
}

4、子项目cc-engine

        4.1 cc-engine的CMakeLists.txt

             这个主要是生成动态库

cmake_minimum_required(VERSION 3.6)

project(CCEngine)

SET(CMAKE_PREFIX_PATH $ENV{QTDIR})

# 找到Qt相关库并导入项目,确保其被正确安装在系统中
find_package(Qt5Core $ENV{QTVERSION} REQUIRED)
find_package(Qt5Gui $ENV{QTVERSION} REQUIRED)
find_package(Qt5Widgets $ENV{QTVERSION} REQUIRED)
find_package(Qt5Network $ENV{QTVERSION} REQUIRED)

file(GLOB_RECURSE All_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.c 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.cc
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.mm 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.hh 
							  ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
							  
cc_source_group_by_dir(All_SOURCES)	
					
set(CMAKE_AUTOMOC ON)                    
set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")

include_directories(${CMAKE_CURRENT_SOURCE_DIR} 
					${Qt5Core_INCLUDE_DIRS}
					${CMAKE_CURRENT_SOURCE_DIR}/include)

if(WIN32)
	set(exe_property WIN32)
	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /Zi /MP /Qpar /Gm-")
	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
	set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")

	add_definitions(-DUNICODE -D_UNICODE -D_SCL_SECURE_NO_WARNINGS -DWIN32 -DCCENGINE_LIB -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB)
	
elseif(APPLE)
    SET(BUILD_WITH_INSTALL_RPATH TRUE)
    set(exe_property MACOSX_BUNDLE)
    set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")	
	add_definitions(-DQT_CORE_LIB -DQT_GUI_LIB)	
elseif(LINUX)
endif(WIN32)


set(NAME CcEngine)

# 生成动态库CcEngine.dylib
add_library(${NAME} SHARED ${All_SOURCES})

if(WIN32)
	add_custom_command(TARGET CcEngine PRE_BUILD COMMAND if exist ${CMAKE_CURRENT_BINARY_DIR}/$(Configuration) cmake -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/$(Configuration))	
elseif(APPLE)
	set_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
	set_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS "YES")
	set_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_SEPARATE_STRIP "YES")
	set_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_STRIP_STYLE "Non-Global Symbols")

    target_link_libraries(${NAME} "-framework CoreVideo" "-framework CoreImage" "-framework CoreGraphics" "-framework AVFoundation")

endif()

if(APPLE)
	set_target_properties(${NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "x86_64")
endif()

# 将Qt的相关模块链接到相关目标(target)中,以使得目标能够使用Qt的相关模块功能
qt5_use_modules(${NAME} Core)
qt5_use_modules(${NAME} Gui)
qt5_use_modules(${NAME} Widgets)
qt5_use_modules(${NAME} Network)
							
target_link_libraries(CcEngine ${Qt5Core_LIBRARIES} ${LINK_LIBRARY})

5、生成项目

5.1 生成xcode工程

        1.主目录中新建build 

        2. cd build

        3. cmake -G"Xcode" ..

          

5.2 生成vistual stdio 2019项目

        1.在主目录中新建build

        2.cd build

        3.cmake -G"Visual Studio 16 2019" -A Win32 ..

        4.在build里面打开CcQtApp.sln解决方案

        

6、gitee上有这个项目工程的源码

       windows macos linux都可以用这个CMake来构建

      链接地址: CcQtApp: Qt测试demo

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值