CMake學習小結

假定有vegagis工程,工程的目錄結構以下:linux

#--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路徑,存放生成的工程文件等app

#////////////////////////////////////////////
#vegagis目錄下的CMakeLists.txt
#///////////////////////////////////////////ui

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)操作系統

#工程名
PROJECT(vegagis)插件

#工程文件中使用相對路徑
SET(CMAKE_SUPPRESS_REGENERATION 1)
SET(CMAKE_USE_RELATIVE_PATHS ON)orm

#支持IF(A) ELSE()的寫法
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)接口

#定義工程的頂級路徑
SET(PROJDIR ${CMAKE_CURRENT_SOURCE_DIR})資源

#定義源文件目錄
SET(SRCDIR ${PROJDIR}/src)get

#設置輸出路徑
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)qt

#設置安裝路徑
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)


#其餘
#一、輸出路徑的問題
#若是要修改輸出路徑,一般採用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爲../。

#二、頭文件安裝時按照目錄層次存放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})

相關文章
相關標籤/搜索