<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    CMake學習小結

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    假定有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 "/" "http://" sgbd_group_name ${sgbd_group_name})
                if(sgbd_nogroup)
                    set(sgbd_group_name "http://")
                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})

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全