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

CMake学习小结的更多相关文章

  1. flex学习小结

    接触到flex一个多月了,今天做一个学习小结.如果有知识错误或者意见不同的地方.欢迎交流指教. 画外音:先说一下,我是怎么接触到flex布局的.对于正在学习的童鞋们,我建议大家没事可以逛逛网站,看看人 ...

  2. Python 学习小结

    python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...

  3. react学习小结(生命周期- 实例化时期 - 存在期- 销毁时期)

    react学习小结   本文是我学习react的阶段性小结,如果看官你是react资深玩家,那么还请就此打住移步他处,如果你想给一些建议和指导,那么还请轻拍~ 目前团队内对react的使用非常普遍,之 ...

  4. objective-c基础教程——学习小结

    objective-c基础教程——学习小结   提纲: 简介 与C语言相比要注意的地方 objective-c高级特性 开发工具介绍(cocoa 工具包的功能,框架,源文件组织:XCode使用介绍) ...

  5. pthread多线程编程的学习小结

    pthread多线程编程的学习小结  pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写     程序员必上的开发者服务平台 —— DevSt ...

  6. ExtJs学习笔记之学习小结LoginDemo

    ExtJs学习小结LoginDemo 1.示例:(登录界面) <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  7. CMake学习(1)---简单程序与库

    cmake是linux平台下重要的工具,可以方便的组织makefile.之前一直在windows平台下进行软件开发,在vs2010的IDE里,只要一点run程序就能跑出结果.但是程序的编译并没有那么简 ...

  8. cmake学习笔记(五)

    在cmake 学习笔记(三) 中简单学习了 find_package 的 model 模式,在cmake 学习笔记(四)中了解一个CMakeCache相关的东西.但靠这些知识还是不能看懂PySide使 ...

  9. cmake 学习笔记(三)

    转自:http://blog.csdn.net/dbzhang800/article/details/6329314 接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cma ...

随机推荐

  1. Objective-C分类 (category)和扩展(Extension)

    1.分类(category) 使用Object-C中的分类,是一种编译时的手段,允许我们通过给一个类添加方法来扩充它(但是通过category不能添加新的实例变量),并且我们不需要访问类中的代码就可以 ...

  2. 刚开始学HTML自己做的,求大神些多多指教。

    !DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> ...

  3. HTML静态网页的格式与布局(position:(fixed、absolute、relative)、分层、float(left、right))

    一.position:fixed 锁定位置(相对于浏览器的位置),例如有些网站的右下角的弹出窗口. 示例: 二.position:absolute 1.外层没有position:absolute(或r ...

  4. Ubuntu_16.04_Lamp

    Ubuntu_16.04安装Lamp开发环境 目录 安装Apache2 安装php5 安装mysql-server 安装php5-mysql(php使用mysql服务,包括mysql,mysqli,m ...

  5. [SAP] 外部系统调用SAP web service用户验证的简单方法

    场景: 一个Java系统调用SAP系统提供的web service,除了根据WSDL生成的代理类,调用相应方法,传入相应参数外,还等需要使用SAP提供的用户信息进行身份验证,最简单的方法是在soap请 ...

  6. iOS开发之AsyncSocket使用教程

    用socket可以实现像QQ那样发送即时消息的功能.客户端和服务端需要建立长连接,在长连接的情况下,发送消息.客户端可以发送心跳包来检测长连接. 在iOS开发中使用socket,一般都是用第三方库As ...

  7. Android应用开发基础篇(13)-----GestureDetector(手势识别)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/05/2381025.html 一.概述 GestureDetector是一个用于识别手势的类,这 ...

  8. C#中网站根路径、应用根路径、物理路径、绝对路径,虚拟路径的区别

    C#中网站根路径,请站点的最外一层 /表示 应用根路径 ~/表示,有时候C#程序路径并不是网站路径 物理路径 server.mappath("~/") 是指应用程序放在服务器硬盘的 ...

  9. MySql 日期字符串类型互转

    1.data_format 日期转字符串 select date_format(Now(), '%Y-%m-%d %H:%i'); 2.str_to_date 字符串转日期 select str_to ...

  10. Bootstrap Collapse使用

    参考 http://wrongwaycn.github.io/bootstrap/docs/javascript.html#collapse http://www.w3resource.com/twi ...