• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            馭風(fēng)萬里無垠

            cmake的一些小經(jīng)驗(yàn)

            初用CMake或者對(duì)其了解不太深的人,可能經(jīng)常會(huì)被路徑包含、庫(kù)搜索路徑、鏈接路徑、RPath這些問題所絆倒,因?yàn)檫@些東西在手工執(zhí)行g(shù)cc或者編寫makefile的時(shí)候是很輕而易舉的任務(wù)。

            其實(shí)我當(dāng)初也有不少疑惑,不過通過較長(zhǎng)時(shí)間的實(shí)踐和閱讀manual,總算有了個(gè)相對(duì)很清晰的認(rèn)識(shí)。

            • 如何使用其manual

            cmake的幫助組織的還是很有規(guī)律的,了解了其規(guī)律,找自己想要的東西就會(huì)很簡(jiǎn)單,所以個(gè)人覺得這一點(diǎn)可能是最重要的。其help系統(tǒng)大概是這么幾類:

              • command

            這個(gè)是實(shí)用過程中最長(zhǎng)用到的,相當(dāng)于一般腳步語言中的基本語法,包括定義變量,foreach,string,if,builtin command都在這里。

            可以用如下這些命令獲取幫助:

            cmake --help-commands
            

            這個(gè)命令將給出所有cmake內(nèi)置的命令的詳細(xì)幫助,一般不知道自己要找什么或者想隨機(jī)翻翻得時(shí)候,可以用這個(gè)。

            我一般更常用的方法是將其重定向到less里邊,然后在編輯器里邊搜索關(guān)鍵字。

             

            另外也可以用如下的辦法層層縮小搜索范圍:

            cmake --help-command-list
            

            cmake --help-command-list | grep find

            skyscribe@skyscribe:~/program/ltesim/bld$ cmake --help-command-list | grep find
            find_file
            find_library
            find_package
            find_path
            find_program

            cmake --help-command find_library

            cmake version 2.6-patch 4
            ------------------------------------------------------------------------------
            SingleItem

              find_library
                   Find a library.

                      find_library(<VAR> name1 [path1 path2 ...])

                   This is the short-hand signature for the command that is sufficient in
                   many cases.  It is the same as find_library(<VAR> name1 [PATHS path1
                   path2 ...])

                      find_library(
                                <VAR>
                                name | NAMES name1 [name2 ...]
                                [HINTS path1 [path2 ... ENV var]]
                                [PATHS path1 [path2 ... ENV var]]
                                [PATH_SUFFIXES suffix1 [suffix2 ...]]
                                [DOC "cache documentation string"]
                                [NO_DEFAULT_PATH]
                                [NO_CMAKE_ENVIRONMENT_PATH]
                                [NO_CMAKE_PATH]
                                [NO_SYSTEM_ENVIRONMENT_PATH]
                                [NO_CMAKE_SYSTEM_PATH]
                                [CMAKE_FIND_ROOT_PATH_BOTH |
                                 ONLY_CMAKE_FIND_ROOT_PATH |
                                 NO_CMAKE_FIND_ROOT_PATH]
                               )

              • variable

            和command的幫助比較類似,只不過這里可以查找cmake自己定義了那些變量你可以直接使用,譬如OSName,是否是Windows,Unix等。

            我最常用的一個(gè)例子:

            cmake --help-variable-list  | grep CMAKE | grep HOST
            
            CMAKE_HOST_APPLE
            
            CMAKE_HOST_SYSTEM
            
            CMAKE_HOST_SYSTEM_NAME
            
            CMAKE_HOST_SYSTEM_PROCESSOR
            
            CMAKE_HOST_SYSTEM_VERSION
            
            CMAKE_HOST_UNIX
            
            CMAKE_HOST_WIN32
            

            這里查找所有CMake自己定義的builtin變量;一般和系統(tǒng)平臺(tái)相關(guān)。

            如果希望將所有生成的可執(zhí)行文件、庫(kù)放在同一的目錄下,可以如此做:

            這里的target_dir是一個(gè)實(shí)現(xiàn)設(shè)置好的絕對(duì)路徑。(CMake里邊絕對(duì)路徑比相對(duì)路徑更少出問題,如果可能盡量用絕對(duì)路徑)

            # Targets directory
            
            set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${target_dir}/lib)
            
            set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${target_dir}/lib)
            
            set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${target_dir}/bin)
            
              • property

            Property一般很少需要直接改動(dòng),除非你想修改一些默認(rèn)的行為,譬如修改生成的動(dòng)態(tài)庫(kù)文件的soname等。

            譬如需要在同一個(gè)目錄下既生成動(dòng)態(tài)庫(kù),也生成靜態(tài)庫(kù),那么默認(rèn)的情況下,cmake根據(jù)你提供的target名字自動(dòng)生成類似的libtarget.so, libtarget.a,但是同一個(gè)project只能同時(shí)有一個(gè),因?yàn)閠arget必須唯一。

            這時(shí)候,就可以通過修改taget對(duì)應(yīng)的文件名,從而達(dá)到既生成動(dòng)態(tài)庫(kù)也產(chǎn)生靜態(tài)庫(kù)的目的。

            譬如:

            cmake --help-property-list | grep NAME
            
            GENERATOR_FILE_NAME
            
            IMPORTED_SONAME
            
            IMPORTED_SONAME_<CONFIG>
            
            INSTALL_NAME_DIR
            
            OUTPUT_NAME
            
            VS_SCC_PROJECTNAME
            
            skyscribe@skyscribe:~$ cmake --help-property OUTPUT_NAME
            
            cmake version 2.6-patch 4
            
            ------------------------------------------------------------------------------
            
            SingleItem
            
              OUTPUT_NAME
            
                   Sets the real name of a target when it is built.
            
                   Sets the real name of a target when it is built and can be used to
            
                   help create two targets of the same name even though CMake requires
            
                   unique logical target names.  There is also a <CONFIG>_OUTPUT_NAME
            
                   that can set the output name on a per-configuration basis.
            
              • module

            用于查找常用的模塊,譬如boost,bzip2, python等。通過簡(jiǎn)單的include命令包含預(yù)定義的模塊,就可以得到一些模塊執(zhí)行后定義好的變量,非常方便。

            譬如常用的boost庫(kù),可以通過如下方式:

            # Find boost 1.40
            
            INCLUDE(FindBoost)
            
            find_package(Boost 1.40.0 COMPONENTS thread unit_test_framework)
            
            if(NOT Boost_FOUND)
            
                message(STATUS "BOOST not found, test will not succeed!")
            
            endif()
            
            一般開頭部分的解釋都相當(dāng)有用,可滿足80%需求:
            
            cmake --help-module FindBoost | head -40
            
            cmake version 2.6-patch 4
            
            ------------------------------------------------------------------------------
            
            SingleItem
            
              FindBoost
            
                   Try to find Boost include dirs and libraries
            
                   Usage of this module as follows:
            
                   == Using Header-Only libraries from within Boost: ==
            
                      find_package( Boost 1.36.0 )
            
                      if(Boost_FOUND)
            
                         include_directories(${Boost_INCLUDE_DIRS})
            
                         add_executable(foo foo.cc)
            
                      endif()
            
                   
            
                   
            
                   == Using actual libraries from within Boost: ==
            
                      set(Boost_USE_STATIC_LIBS   ON)
            
                      set(Boost_USE_MULTITHREADED ON)
            
                      find_package( Boost 1.36.0 COMPONENTS date_time filesystem system ... )
            
                   
            
                      if(Boost_FOUND)
            
                         include_directories(${Boost_INCLUDE_DIRS})
            
                         add_executable(foo foo.cc)
            
                         target_link_libraries(foo ${Boost_LIBRARIES})
            
                      endif()
            
                   
            
                   
            
                   The components list needs to contain actual names of boost libraries
            
            • 如何根據(jù)其生成的中間文件查看一些關(guān)鍵信息

            CMake相比較于autotools的一個(gè)優(yōu)勢(shì)就在于其生成的中間文件組織的很有序,并且清晰易懂,不像autotools會(huì)生成天書一樣的龐然大物(10000+的不鮮見)。

            一般CMake對(duì)應(yīng)的Makefile都是有層級(jí)結(jié)構(gòu)的,并且會(huì)根據(jù)你的CMakeLists.txt間的相對(duì)結(jié)構(gòu)在binary directory里邊生成相應(yīng)的目錄結(jié)構(gòu)。

            譬如對(duì)于某一個(gè)target,一般binary tree下可以找到一個(gè)文件夾:  CMakeFiles/<targentName>.dir/,比如:

            skyscribe@skyscribe:~/program/ltesim/bld/dev/simcluster/CMakeFiles/SIMCLUSTER.dir$ ls -l
            
            total 84
            
            -rw-r--r-- 1 skyscribe skyscribe 52533 2009-12-12 12:20 build.make
            
            -rw-r--r-- 1 skyscribe skyscribe  1190 2009-12-12 12:20 cmake_clean.cmake
            
            -rw-r--r-- 1 skyscribe skyscribe  4519 2009-12-12 12:20 DependInfo.cmake
            
            -rw-r--r-- 1 skyscribe skyscribe    94 2009-12-12 12:20 depend.make
            
            -rw-r--r-- 1 skyscribe skyscribe   573 2009-12-12 12:20 flags.make
            
            -rw-r--r-- 1 skyscribe skyscribe  1310 2009-12-12 12:20 link.txt
            
            -rw-r--r-- 1 skyscribe skyscribe   406 2009-12-12 12:20 progress.make
            
            drwxr-xr-x 2 skyscribe skyscribe  4096 2009-12-12 12:20 src
            
            這里,每一個(gè)文件都是個(gè)很短小的文本文件,內(nèi)容相當(dāng)清晰明了。build.make一般包含中間生成文件的依賴規(guī)則,DependInfo.cmake一般包含源代碼文件自身的依賴規(guī)則。
            比較重要的是flags.make和link.txt,前者一般包含了類似于GCC的-I的相關(guān)信息,如搜索路徑,宏定義等;后者則包含了最終生成target時(shí)候的linkage信息,庫(kù)搜索路徑等。
            這些信息在出現(xiàn)問題的時(shí)候是個(gè)很好的輔助調(diào)試手段。
            • 文件查找、路徑相關(guān)
              • include

            一般常用的是:

            include_directories()用于添加頭文件的包含搜索路徑
            
            cmake --help-command include_directories
            
            cmake version 2.6-patch 4
            
            ------------------------------------------------------------------------------
            
            SingleItem
            
              include_directories
            
                   Add include directories to the build.
            
                     include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
            
                   Add the given directories to those searched by the compiler for
            
                   include files.  By default the directories are appended onto the
            
                   current list of directories.  This default behavior can be changed by
            
                   setting CMAKE_include_directories_BEFORE to ON.  By using BEFORE or
            
                   AFTER you can select between appending and prepending, independent
            
                   from the default.  If the SYSTEM option is given the compiler will be
            
                   told that the directories are meant as system include directories on
            
                   some platforms.
            
            link_directories()用于添加查找?guī)煳募乃阉髀窂?
            
            cmake --help-command link_directories
            
            cmake version 2.6-patch 4
            
            ------------------------------------------------------------------------------
            
            SingleItem
            
              link_directories
            
                   Specify directories in which the linker will look for libraries.
            
                     link_directories(directory1 directory2 ...)
            
                   Specify the paths in which the linker should search for libraries.
            
                   The command will apply only to targets created after it is called.
            
                   For historical reasons, relative paths given to this command are
            
                   passed to the linker unchanged (unlike many CMake commands which
            
                   interpret them relative to the current source directory).
            
              • library search

            一般外部庫(kù)的link方式可以通過兩種方法來做,一種是顯示添加路徑,采用link_directories(), 一種是通過find_library()去查找對(duì)應(yīng)的庫(kù)的絕對(duì)路徑。

            后一種方法是更好的,因?yàn)樗梢詼p少不少潛在的沖突。

                    一般find_library會(huì)根據(jù)一些默認(rèn)規(guī)則來搜索文件,如果找到,將會(huì)set傳入的第一個(gè)變量參數(shù)、否則,對(duì)應(yīng)的參數(shù)不被定義,并且有一個(gè)xxx-NOTFOUND被定義;可以通過這種方式來調(diào)試庫(kù)搜索是否成功。

                    對(duì)于庫(kù)文件的名字而言,動(dòng)態(tài)庫(kù)搜索的時(shí)候會(huì)自動(dòng)搜索libxxx.so (xxx.dll),靜態(tài)庫(kù)則是libxxx.a(xxx.lib),對(duì)于動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)混用的情況,可能會(huì)出現(xiàn)一些混亂,需要格外小心;一般盡量做匹配連接。

              • rpath

            所謂的rpath是和動(dòng)態(tài)庫(kù)的加載運(yùn)行相關(guān)的。我一般采用如下的方式取代默認(rèn)添加的rpath:

            # RPATH and library search setting
            
            SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
            
            SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 
            
            SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/nesim/lib")
            
            SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 

             

            posted on 2009-12-14 20:39 skyscribe 閱讀(29131) 評(píng)論(1)  編輯 收藏 引用

            評(píng)論

            # re: cmake的一些小經(jīng)驗(yàn) 2014-09-17 09:58 雷鋒

            我研究了好幾天了,老是找不到包含文件  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            <2025年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            亚洲午夜久久久久妓女影院| 97久久久久人妻精品专区| 久久久久综合国产欧美一区二区 | 国产高潮国产高潮久久久91| 91久久九九无码成人网站 | 伊人久久亚洲综合影院| 少妇高潮惨叫久久久久久 | 狠狠色丁香久久综合五月| 日韩美女18网站久久精品| 久久精品人人做人人爽电影蜜月| A级毛片无码久久精品免费| 性欧美丰满熟妇XXXX性久久久| 久久国产精品久久精品国产| 亚洲精品第一综合99久久| 国产精品久久久久影院色| 亚洲国产精品成人久久蜜臀| segui久久国产精品| 91久久精一区二区三区大全| 欧美精品国产综合久久| 欧美激情精品久久久久久| 九九99精品久久久久久| 亚洲精品无码久久久影院相关影片 | 国内精品久久久久影院网站| 久久棈精品久久久久久噜噜| 99久久综合国产精品免费| 久久久久亚洲AV综合波多野结衣| 久久精品欧美日韩精品| 久久精品国产免费观看| 久久久久这里只有精品 | 性高朝久久久久久久久久| 伊人久久大香线焦综合四虎| 久久99热国产这有精品| 精品久久无码中文字幕| 久久精品亚洲中文字幕无码麻豆| 久久久久亚洲精品日久生情| 99久久国产精品免费一区二区| 97香蕉久久夜色精品国产| 久久久久亚洲AV无码专区首JN| 亚洲国产视频久久| 久久精品国产2020| 久久综合九色综合网站|