CMake学习小结

假定有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})

时间: 2024-11-14 11:14:58

CMake学习小结的相关文章

git学习小结

背景:最近因为工作原因,需要将以前的代码库由bitbucket重新布置在一台服务器上,所以就学习了下git,特此记录下 在167这台机器上搭建apache,用做git server,由于以前apache都已经搭好了,所以这里只配置git server 就可以了,此处贴出配置: 服务器搭好了,来到配置中的root目录,git clone https://[email protected]/XXXX 此时,库和服务器都搭好了,用于新库测试的机器也可以从git server上克隆库了,来,我们来试试从

网络编程学习小结

几种网络编程方式: ISAPI.CGI.WinInet.Winsock 它们之间的差别: 1)  ISAPI主要是开发基于浏览器client与server端程序.效率比CGI方式高,并且也扩展了CGI没有的一些功能.(基于TCP/IP模型中的应用层) 2)  CGI主要是开发基于浏览器client与server端程序.(基于TCP/IP模型中的应用层) 3)  WinInet主要是开发client程序.(基于TCP/IP模型中的应用层) 4)  Winsock主要是基于socket来开发clie

MogileFS学习小结

大纲: 一.关于MogileFS 二.常见分布式文件系统 三.MogileFS基本原理 四.MogileFS的实现 一.关于MogileFS 当下我们处在一个互联网飞速发展的信息社会,在海量并发连接的驱动下每天所产生的数据量必然以几何方式增长,随着信息连接方式日益多样化,数据存储的结构也随着发生了变化.在这样的压力下使得人们不得不重新审视大量数据的存储所带来的挑战,例如:数据采集.数据存储.数据搜索.数据共享.数据传输.数据分析.数据可视化等一系列问题. 传统存储在面对海量数据存储表现出的力不从

201671010130 2016-2017-2 《Java程序设计》第四周学习小结

第四周学习小结 本次实验巩固了上次实验分隔数并求和的题,目前这个题有两种做法,一种是不断对数10求余,余数保存在sum中,然后左移一位,直到余数为零.另一种就是将数字强制转换成一个字符串数组String s=String.valueOf(num),根据方法s.toCharArray()将字符分离出来,据"x"-"0"=x,unicode码值相减即可得x的值. 父类和子类能够看两个交集,super关键字是否能够看做一个子类和超类的接口呢? 在子类中可以增加域.增加方法

初识ASP.NET---点滴的积累---ASP.NET学习小结

差不多十多天前学习完了北大青鸟的学习视频,没想到没几天的时间就看完了XML视频和牛腩的Javascript视频.学习完了也该总结总结,理理自己的思路,消化一下自己学习到的东西. 视频中的理论知识并不是很多,以例子驱动学起来也不会他过于乏味.全部的学习内容大概的可以用下图表示. 个人感觉这套视频的体系感不是很强,每一集之间老师的串联并不是做得很好,向我等没有教材的有些小的知识无从知晓.但是不能不说这套视频确很适合初学者学习,老师讲解的也不错,从此我也算是入门. 当然要想进一步的了解ASP.NET并

8086汇编学习小结———实时更新

初学IBM-PC 8086,对INT指令不是很理解.现从网上总计如下: 表:DOS系统功能调INT 21H AH 功能 调用参数 返回参数 00 程序终止(同INT 20H) CS=程序段前缀 01 键盘输入并回显 AL=输入字符 02 显示输出 DL=输出字符 03 异步通迅输入 AL=输入数据 04 异步通迅输出 DL=输出数据 05 打印机输出 DL=输出字符 06 直接控制台I/O DL=FF(输入)DL=字符(输出) AL=输入字符 07 键盘输入(无回显) AL=输入字符 08 键盘

《Pro AngularJS》学习小结-01

<Pro AngularJS>该书以一个SportsStore案例为主线铺开. 一.开发环境设置 该书中所用的server开发环境是Deployed,从来没听说过,而且作者也说该server没什么人用,我干脆弃用之.其他的环境包括 NodeJS--这个必须装 karma--测试环境,前期还没有用到,以后认真研究,毕竟AngularJS一大特点是Unit Test bootstrap--这个现在应该普遍使用了,O(∩_∩)O webstorm--现在唯一支持AngularJS插件的IDE 我基本

自动化测试Selenium Webdriver (JAVA)学习小结

自动化测试--Selenium学习小结 一.自动化测试的概念及意义: 1.什么是自动化测试: 一般是指软件测试的自动化,软件测试就是在预设条件下运行系统或应用程序,评估运行结果,预先条件应包括正常条件和异常条件. 2.意义: 让测试更有效率,利用更多的空余时间,减少人力资源. 二.selenium工具 我用的是java语言,所以接下来的例子和方法都是基于java的. 1.环境配置 (1)Jdk的配置: 我用的是1.7的jdk,配置方法都一样,新建一个JAVA_HOME,把你装好的jdk的路径复制

点滴的积累---J2SE学习小结

点滴的积累---J2SE学习小结 什么是J2SE J2SE就是Java2的标准版,主要用于桌面应用软件的编程:包括那些构成Java语言核心的类.比方:数据库连接.接口定义.输入/输出.网络编程. 学习感受 近半个月的坎坷,总算是将马士兵的<J2SE教程>视频看完了,期间一些其它的事一些不得不处理的事总是打断我的安排.看了视频之后认为东西确实都非常基础给我印象最深的是关于程序执行的内存分析.IO和线程,这谁在之前不管是学习VB.VB.NET还是C#中都没怎么设计到的东西. 首先,我想对于一个初学