CMake学习

tech2023-06-22  109

假定有vegagis工程,工程的目录结构如下:

#--vegagis # |--src 源文件目录 # |--gui 界面工程,输出类型:dll,依赖于QT的QtCore、QtGui、QtXml # |--pending 工程中的源文件,不希望加入到工程中 # ## 为了实现跨平台运行,win32和linux目录下实现的是同一套接口,win32不编译linux目录,linux下则不编译win32目录,但是工程中包含这两个目录 # |--win32 win32下的实现 # |--linux linux下的实现 # |--app 应用程序,输出类型:exe,它依赖于gui # |--include 安装时头文件输出的目录 # |--gui # |--app # |--bin 输出路径,存放dll和exe # |--Debug # |--plugins # |--build CMake的build路径,存放生成的工程文件等 # #vegagis目录下的CMakeLists.txt #/// CMAKE_MINIMUM_REQUIRED(VERSION 2.8) #工程名 PROJECT(vegagis) #工程文件中使用相对路径 SET(CMAKE_SUPPRESS_REGENERATION 1) SET(CMAKE_USE_RELATIVE_PATHS ON) #支持IF(A) ELSE()的写法 SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) #定义工程的顶级路径 SET(PROJDIR ${CMAKE_CURRENT_SOURCE_DIR}) #定义源文件目录 SET(SRCDIR ${PROJDIR}/src) #设置输出路径 SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) #设置安装路径 SET(CMAKE_INSTALL_PREFIX ${PROJDIR}/bin) #定义头文件安装目录 SET(VGIS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/headers) #根据操作系统不同而设置不同的路径 IF(WIN32) SET(GDAL_HDRS "E:/lib/gdal/include") ELSE() SET(GDAL_HDRS "/home/sunsc/gdal/") ENDIF() #设置头文件的引用路径 INCLUDE_DIRECTORIES( ${GDAL_HDRS} ) #设置引用库路径 SET(LIBS ${LIBRARY_OUTPUT_PATH}) LINK_DIRECTORIES(${LIBS}) #设置依赖库Qt4 SET(QT_MIN_VERSION 4.5.2) FIND_PACKAGE(Qt4 ${QT_MIN_VERSION} COMPONENTS QtCore QtGui QtXml REQUIRED) INCLUDE(${QT_USE_FILE}) #宏,实现visio studio的目录分组(过滤器)功能 macro(source_group_by_dir source_files) if(MSVC) set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR}) foreach(sgbd_file ${${source_files}}) string(REGEX REPLACE ${sgbd_cur_dir}//(.*/) //1 sgbd_fpath ${sgbd_file}) string(REGEX REPLACE "/(.*/)/.*" //1 sgbd_group_name ${sgbd_fpath}) string(COMPARE EQUAL ${sgbd_fpath} ${sgbd_group_name} sgbd_nogroup) string(REPLACE "/" "//" sgbd_group_name ${sgbd_group_name}) if(sgbd_nogroup) set(sgbd_group_name "//") endif(sgbd_nogroup) source_group(${sgbd_group_name} FILES ${sgbd_file}) endforeach(sgbd_file) endif(MSVC) endmacro(source_group_by_dir) #添加子目录 ADD_SUBDIRECTORY(src) # #vegagis/src目录下的CMakeLists.txt #/// ADD_SUBDIRECTORY(gui) ADD_SUBDIRECTORY(app) #添加依赖关系 ADD_DEPENDENCIES(APP GUI) # #vegagis/src/gui目录下的CMakeLists.txt #/// SET(TARGET_NAME GUI) #预定义宏,-D选项 ADD_DEFINITIONS(-DVMAP_GUI_LIB) #ui文件 SET(GUI_UIS vmapmainwindow.ui) #源文件类型为*.h**.c* FILE(GLOB_RECURSE GUI_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.c* ${CMAKE_CURRENT_SOURCE_DIR}/*.h*) #FILE目前还不支持类似EXCLUDE的特性,所以Pending中的文件在上一语句中叶包括了,我们删除它 FILE(GLOB PENDING ${CMAKE_CURRENT_SOURCE_DIR}/pending/*) LIST(REMOVE_ITEM GUI_SRCS ${PENDING}) #新生成的GUI_SRCS就不包括pending目录的源文件了 #参与QT MOC的头文件 FILE(GLOB_RECURSE GUI_MOC_HDRS vmapview.h transformlistener.hpp) #设置资源qrc文件 SET (GUI_RCCS ui.qrc) QT4_WRAP_UI(GUI_UIS_H ${GUI_UIS}) QT4_WRAP_CPP(GUI_MOC_SRCS ${GUI_MOC_HDRS}) QT4_ADD_RESOURCES(GUI_RCC_SRCS ${GUI_RCCS}) #由于.ui文件输出路径是在build目录下,所以需要添加${CMAKE_CURRENT_BINARY_DIR}目录 INCLUDE_DIRECTORIES(${SRCDIR}/gui ${CMAKE_CURRENT_BINARY_DIR}) #设置需要加入到工程中,但是不需要编译的源文件 IF (WIN32) FILE(GLOB_RECURSE PLATFORM_SRC "${CMAKE_CURRENT_SOURCE_DIR}/linux/*") ELSE() FILE(GLOB_RECURSE PLATFORM_SRC "${CMAKE_CURRENT_SOURCE_DIR}/win32/*") ENDIF() FILE(GLOB_RECURSE EXCLUDE_SRC ${PLATFORM_SRC}) SET_SOURCE_FILES_PROPERTIES(${EXCLUDE_SRC} PROPERTIES HEADER_FILE_ONLY true) #设置源文件属性为不参与编译 #进行源代码分组 source_group_by_dir(GUI_SRCS) #动态链接库 ADD_LIBRARY(${TARGET_NAME} SHARED ${GUI_SRCS} ${GUI_UIS_H} ${GUI_RCC_SRCS} ${GUI_MOC_SRCS}) TARGET_LINK_LIBRARIES(${TARGET_NAME} ${QT_LIBRARIES}) #// #vegagis/src/app下的CMakeLists.txt #// SET(TARGET_NAME APP) SET(APP_UIS vmapmainwindow.ui) FILE(GLOB_RECURSE APP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/*.c* ${CMAKE_CURRENT_SOURCE_DIR}/*.h*) SET (APP_MOC_HDRS vmapmainwindow.h) SET (APP_RCCS vmapmainwindow.qrc) QT4_WRAP_UI(APP_UIS_H ${APP_UIS}) QT4_WRAP_CPP(APP_MOC_SRCS ${APP_MOC_HDRS}) QT4_ADD_RESOURCES(APP_RCC_SRCS ${APP_RCCS}) #添加头文件 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${SRCDIR}/apps/qt/${TARGET_NAME}) #源文件分组 source_group_by_dir(APP_SRCS) #exe应用程序 ADD_EXECUTABLE(${TARGET_NAME} ${APP_SRCS} ${APP_RCC_SRCS} ${APP_UIS_H} ${APP_MOC_SRCS}) #TARGET_LINK_LIBRARIES语句必须放到ADD_EXECUTABLE语句之后,否则引起链接错误 TARGET_LINK_LIBRARIES(${TARGET_NAME} ${QT_LIBRARIES} GUI) #其他 #1、输出路径的问题 #如果要修改输出路径,通常采用SET(LIBRARY_OUTPUT_PATH XXX)即可,但是在WIN32下,会自动放到${XXX}/Debug/Release目录下,比如有一个插件,希望在输出目录的plugins子目录下,但是如果设定为SET(LIBRARY_OUTPUT_PATH XXX/plugins),则文件输出目录为${XXX}/plugins/Debug,这显然不是我们希望的。做法是设置PREFIX,如SET_TARGET_PROPERTIES(abc PROPERTIES PREFIX plugins/)。同理,如果输出路径不管Debug、Release都放置一样,则设置PREFIX为../#2、头文件安装时按照目录层次存放 FILE(GLOB_RECURSE HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h*) FOREACH (HEADER ${HEADERS}) STRING(REGEX MATCH "(.*)[///]" DIR ${HEADER}) INSTALL(FILES ${HEADER} DESTINATION ${VGIS_INCLUDE_DIR}/${DIR}) ENDFOREACH(HEADER ${HEADERS})
最新回复(0)