前段时间搭建工程,一直在编写Cmakelist.txt文档,从中也收获许多,这篇文档写一些实用的,需要注意的CmakeList的小tip,希望能给自己做个总结,下次不要犯错


这里写几个我修改CmakeList时遇到的点,以后遇到了再继续补充:


  1. # include directories
    include_directories(
            3rd_party/include
            3rd_party/include/icu
            3rd_party/include/pcre
            code/include
            code/include/common
            code/include/common/utils
            code/include/server
            code/include/QueryEngine
            code/include/QueryEngine/pseport
            code/include/StorageEngine
            code/include/GraphEngine
            code/include/GraphEngine/include
            code/include/GraphEngine/include/rasqal
            code/include/GraphEngine/include/raptor2
            )

    在最外层的CmakeList中添加包含路径include_directories,则其子工程中都会被添加进该包含路径


  2. if(CMAKE_SIZEOF_VOID_P EQUAL 8 )
        set(ARCH_NAME x64)
    else(CMAKE_SIZEOF_VOID_P EQUAL 4 )
        set(ARCH_NAME x86)
    endif (CMAKE_SIZEOF_VOID_P EQUAL 8 )
    message(STATUS "ARCH_NAME is ${ARCH_NAME}")
    set(CMAKE_LINK_PATH "3rd_party/lib/${CMAKE_SYSTEM_NAME}/${ARCH_NAME}" ${CMAKE_LINK_PATH})

    我的理解是,通过判断这个"P"(也许是个point变量),如果是4字节,则认为是X86系统,如果是8字节则认为是X64系统,借此设置ARCH_NAME,而CMAKE_SYSTEM_NAME应该是系统信息,Cmake时自动设置好的,所以这样我们就设置成功了一条CMAKE_LINK_PATH,他会根据你的系统平台和系统操作系统自动选择加载合适的LinkPath路径,对于大型的数据库来说,你的第三方库也许会因为平台和位数而不一样,这样设置大大简化的CMake的编写



  3. link_directories(${CMAKE_LINK_PATH}/boost
                     ${CMAKE_LINK_PATH}/gettext
                     ${CMAKE_LINK_PATH}/log4cxx
                     ${CMAKE_LINK_PATH}/zlib
                     ${CMAKE_LINK_PATH}/openssl
                     ${CMAKE_LINK_PATH}/apache
                     ${CMAKE_LINK_PATH}/icu
                     ${CMAKE_LINK_PATH}/odbc
                     ${XMLLIB_LINK_PATH}
                     ${CMAKE_LINK_PATH}/pcre)

    添加Link路径,如是写


4

将某一个工程放置于某一个文件夹下(指的是工程位于某目录)

set_property(TARGET DBProtocol                              PROPERTY FOLDER "Common")
set_property(TARGET NetLib                                  PROPERTY FOLDER "Common")
set_property(TARGET CommonUtils                             PROPERTY FOLDER "Common")
if (MSVC)
    set_property(TARGET pthread                             PROPERTY FOLDER "Common")
endif (MSVC)

其中MSVC = Microsoft VC++;这样就可以将NetLib放置于Common目录下,如下图所示

wKioL1MUMTfTFbcTAABH-nmJFKQ106.jpg

后面的if(MSVC)的意思是如果用的是VS编辑器则继续添加相关....


5

if (MSVC)
set (ext ".dll")
set (dic ".dic")
file(GLOB gettextfiles  ${CMAKE_LINK_PATH}/gettext/*${ext})
file(GLOB zlibfiles  ${CMAKE_LINK_PATH}/zlib/*${ext})
file(GLOB opensslfiles  ${CMAKE_LINK_PATH}/openssl/*${ext})
file(GLOB log4cxxfiles  ${CMAKE_LINK_PATH}/log4cxx/*${ext})
file(GLOB log4cxxfilesdebug ${CMAKE_LINK_PATH}/log4cxx/*d${ext})
list(REMOVE_ITEM log4cxxfiles ${log4cxxfilesdebug})
file(GLOB icufiles  ${CMAKE_LINK_PATH}/icu/*${ext})
file(GLOB icufilesdebug  ${CMAKE_LINK_PATH}/icu/*d${ext})
list(REMOVE_ITEM icufiles ${icufilesdebug})
foreach ( f ${boost_file_names})
    set (boostfiles ${boostfiles}  ${CMAKE_LINK_PATH}/boost/boost_${f}-vc90-mt-1_48${ext})
    set (boostfilesdebug ${boostfilesdebug} ${CMAKE_LINK_PATH}/boost/boost_${f}-vc90-mt-gd-1_48${ext})
endforeach(f)
file(GLOB pcrefiles ${CMAKE_LINK_PATH}/pcre/*${ext})
file(GLOB pcrefilesdebug  ${CMAKE_LINK_PATH}/pcre/*d${ext})
list(REMOVE_ITEM pcrefiles ${pcrefilesdebug})
install(FILES ${gettextfiles}
        ${log4cxxfilesdebug}
        ${zlibfiles}
        ${opensslfiles}
        ${icufiles}
        ${boostfilesdebug}
        ${pcrefiles}
       CONFIGURATIONS Debug
       DESTINATION bin
       )

这个CMakeList写得很有意思,像编程一样,不知道是我们组的那个大神写得,核心功能是将.dll和.dic文件拷贝到bin目录下,方便从VS中直接Debug启动实例,例如

install(FILES ${CMAKE_LINK_PATH}/odbc/libodbc.so DESTINATION bin)

这个例子,就是将libodbc.so拷贝至bin目录下


6

wKioL1MUM_nBKCeIAAExrG_rXpo052.jpg

当你想添加一个子目录时,需要修改该层目录CMakeLists,如下

add_subdirectory(xerces-c-src)
add_subdirectory(xqilla)
add_subdirectory(dbxml)
add_subdirectory(fulltextSearch)


7

更改某一个工程为何种性质的工程


DLL:add_library(fulltextSearch SHARED ${fulltextSearch})


LIB: add_library(fulltextSearch STAITC ${fulltextSearch})


EXE: add_executable(InitXdb ${InitXdb})



8

在FulltextSearch工程下加入Sphinx文件夹,并将FulltextSearch设置为DLL库,并添加相关包含路径,Link路径,函数依赖等,下面走一个完整的流程


首先构建该Sphinx文件夹

set(Sphinx)


其次添加Sphinx头文件目录

#set the LibSphinx  include files.
set(LibSphinx_header_files
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinx.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxstd.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/tokenizer_zhcn.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxexcerpt.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxexpr.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxfilter.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxquery.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxstem.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxtimers.h
    ../../../../code/include/QueryEngine/fulltextSearch/sphinx/sphinxutils.h
)

注意这里,因为这个CMakelist是在src文件夹,故默认目录也在src下,故你需要退出来进入include文件下才能指定到h目录位置


紧接着添加源文件

set(LibSphinx_source_files
    sphinx/sphinx.cpp
    sphinx/sphinxexcerpt.cpp
    sphinx/sphinxexpr.cpp
    sphinx/sphinxfilter.cpp
    sphinx/sphinxmetaphone.cpp
    sphinx/sphinxquery.cpp
    sphinx/sphinxsort.cpp
    sphinx/sphinxsoundex.cpp
    sphinx/sphinxstd.cpp
    sphinx/sphinxstemcz.cpp
    sphinx/sphinxstemen.cpp
    sphinx/sphinxstemru.cpp
    sphinx/sphinxutils.cpp
    sphinx/tokenizer_zhcn.cpp
)

因为当前目录就在src下直接进入下一级目录即可


将目录加入SourceGroup下

source_group("fulltextSearch\\Source Files\\LibSphinx" FILES ${LibSphinx_source_files})
source_group("fulltextSearch\\Header Files\\LibSphinx" FILES ${LibSphinx_header_files})


将所有文件的隶属关系进行链接

# append all files to the fullTextSearch
set (fulltextSearch
    ${fulltextSearch}
    ${fulltextSearch_head_files}
    ${fulltextSearch_source_files}
    ${anaylyzer}
    ${analyzer_header_files}
    ${analyzer_source_files}
    ${framework}
    ${framework_head_files}
    ${framework_source_files}
    ${LibSphinx_source_files}
    ${LibSphinx_header_files}
    ${mmseg_source_files}
    ${mmseg_header_files}
                                                                             
)


设置为动态库模式

add_library(fulltextSearch SHARED ${fulltextSearch})


添加包含路径

include_directories(include
 ${CMAKE_SOURCE_DIR}/3rd_party/include/LibSphinx/expat
 ${CMAKE_SOURCE_DIR}/3rd_party/include/LibSphinx/iconv
 ${CMAKE_SOURCE_DIR}/code/include/StorageEngine
 ${CMAKE_SOURCE_DIR}/code/include/QueryEngine
 ${CMAKE_SOURCE_DIR}/code/include/QueryEngine/fulltextSearch
 ${CMAKE_SOURCE_DIR}/code/include/QueryEngine/fulltextSearch/sphinx
 ${CMAKE_SOURCE_DIR}/code/include/QueryEngine/fulltextSearch/sphinx/mmseg
 ${CMAKE_SOURCE_DIR}/code/src/QueryEngine/dbxml/src
 ${CMAKE_SOURCE_DIR}/code/src/QueryEngine/
 ${CMAKE_SOURCE_DIR}/code/src/QueryEngine/xerces-c-src/src
 ${CMAKE_SOURCE_DIR}/code/src/QueryEngine/xerces-c-src
 ${CMAKE_SOURCE_DIR}/code/src/QueryEngine/xqilla/include
)

添加Link路径

(link路径在最外层的CMakeList中就已经添加好了,这里只需要直接填写link对象即可)


添加Link对象

if (MSVC)
    target_link_libraries(fulltextSearch  icuuc icudt icuin expat  iconv)
else (MSVC)
    target_link_libraries(fulltextSearch icuuc icudata icui18n expat  iconv)
endif (MSVC)

添加工程依赖

add_dependencies(fulltextSearch xerces CommonUtils iconv expat )



最后就是将工程进行编译

install(TARGETS fulltextSearch
    RUNTIME DESTINATION bin
    LIBRARY DESTINATION bin
    ARCHIVE DESTINATION lib)



整个的目前总结的就这么多,以后如果再学到新的东西,我再加进来,顺便上传一本书,叫做CMAKE Practice是本中文书哦,很好,主要是讲Linux下的CMAKE编译相关知识,学习一下吧