<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 15.1 如何開始遷移項目 我們將首先說明,在哪里可以找到我們的示例,然后對移植,進行逐步的討論。 ## 復制要移植的示例 我們將從Vim源代碼庫的v8.1.0290發行標記開始(https://github.com/vim/vim) ,我們的工作基于Git提交哈希值b476cb7進行。 通過克隆Vim的源代碼庫并檢出特定版本的代碼,可以復制以下步驟: ```shell $ git clone --single-branch -b v8.1.0290 https://github.com/vim/vim.git ``` 或者,我們的解決方案可以在`cmake-support`分支上找到,網址是 https://github.com/dev-cafe/vim ,并使用以下方法克隆下來: ```shell $ git clone --single-branch -b cmake-support https://github.com/dev-cafe/vim ``` 在本例中,我們將使用CMake模擬` ./configure --enable-gui=no`的配置方式。 為了與后面的解決方案進行比較,建議讀者也可以研究以下Neovim項目(https://github.com/neovim/neovim ),這是傳統Vi編輯器的一個分支,提供了一個CMake構建系統。 ## 創建一個主CMakeLists.txt 首先,我們在源代碼存儲庫的根目錄中創建主`CMakeLists.txt`,在這里我們設置了最低CMake版本、項目名稱和支持的語言,在本例中是C: ```cmake cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(vim LANGUAGES C) ``` 添加任何目標或源之前,可以設置默認的構建類型。本例中,我們默認為Release配置,這將打開某些編譯器優化選項: ```cmake if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) endif() ``` 我們也使用可移植的安裝目錄變量: ```cmake include(GNUInstallDirs) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) ``` 作為一個完整性檢查,我們可以嘗試配置和構建項目,但到目前為止還沒有目標,所以構建步驟的輸出是空的: ```shell $ mkdir -p build $ cd build $ cmake .. $ cmake --build . ``` 我們一會兒就要開始添加目標了。 ## 如何讓常規和CMake配置共存 CMake的一個特性是在源代碼之外構建,構建目錄可以是任何目錄,而不必是項目目錄的子目錄。這意味著,我們可以將一個項目移植到CMake,而不影響以前/現在的配置和構建機制。對于一個重要項目的遷移,CMake文件可以與其他構建框架共存,從而允許一個漸進的遷移,包括選項、特性和可移植性,并允許開發社區人員適應新的框架。為了允許傳統配置和CMake配置共存一段時間,一個典型的策略是收集`CMakeLists.txt`文件中的所有CMake代碼,以及CMake子目錄下的所有輔助CMake源文件的示例中,我們不會引入CMake子目錄,而是保持輔助文件要求他們接近目標和來源,但會顧及使用的傳統Autotools構建修改的所有文件,但有一個例外:我們將一些修改自動生成文件構建目錄下,而不是在源代碼樹中。 ```shell $ ./configure --enable-gui=no ... lot of output ... $ make > build.log ``` 我們的示例中(這里沒有顯示build.log的內容),我們能夠驗證編譯了哪些源文件以及使用了哪些編譯標志(`-I. -Iproto -DHAVE_CONFIG_H -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1`)。日志文件中,我們可以做如下推斷: * 所有對象文件都鏈接到二進制文件中 * 不生成庫 * 可執行目標與下列庫進行連接:`-lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE -lm -ltinfo -lelf -lnsl -lacl -lattr -lgpm -ldl` 通過在使用`message`對工程進行調試時,選擇添加選項、目標、源和依賴項,我們將逐步實現一個可工作的構建。 ## 獲取傳統構建的記錄 向配置添加任何目標之前,通常有必要看看傳統構建的行為,并將配置和構建步驟的輸出保存到日志文件中。對于我們的Vim示例,可以使用以下方法實現: ```shell $ ./configure --enable-gui=no ... lot of output ... $ make > build.log ``` 示例中(這里沒有顯示build.log的完整內容),我們能夠驗證編譯了哪些源文件以及使用了哪些編譯標志(`-I.-Iproto -DHAVE_CONFIG_H -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1`)。從日志文件中,推斷如下: * 所有對象文件都鏈接到一個二進制文件中 * 沒有生成庫 * 可執行目標鏈接到以下庫:`-lSM -lXpm -lXt -lX11 -lXdmcp -lSM -lSM - linfo -lelf -lnsl -lacl -lattr -lgpm -ldl` ## 調試遷移項目 當目標和命令逐漸移動到CMake端時,使用`message`命令打印變量的值就非常有用了: ```cmake message(STATUS "for debugging printing the value of ${some_variable}") ``` 在使用消息進行調試時,添加選項、目標、源和依賴項,我們將逐步實現一個可工作的構建。 ## 實現選項 找出傳統配置為用戶提供的選項(例如,通過` ./configure --help`)。Vim項目提供了一個非常長的選項和標志列表,為了使本章的討論保持簡單,我們只在CMake端實現四個選項: ```shell --disable-netbeans Disable NetBeans integration support. --disable-channel Disable process communication support. --enable-terminal Enable terminal emulation support. --with-features=TYPE tiny, small, normal, big or huge (default: huge) ``` 我們還將忽略任何GUI支持和模擬`--enable-gui=no`,因為它將使示例復雜化。 我們將在CMakeLists.txt中添加以下選項(有默認值): ```cmake option(ENABLE_NETBEANS "Enable netbeans" ON) option(ENABLE_CHANNEL "Enable channel" ON) option(ENABLE_TERMINAL "Enable terminal" ON) ``` 我們可以用`cmake -D FEATURES=value`定義的變量`FEATURES`來模擬`--with-features `標志。如果不進行設置,它默認值為"huge": ```cmake if(NOT FEATURES) set(FEATURES "huge" CACHE STRING "FEATURES chosen by the user at CMake configure time") endif() ``` 我們為使用者提供了一個值`FEATURES`: ```cmake list(APPEND _available_features "tiny" "small" "normal" "big" "huge") if(NOT FEATURES IN_LIST _available_features) message(FATAL_ERROR "Unknown features: \"${FEATURES}\". Allowed values are: ${_available_features}.") endif() set_property(CACHE FEATURES PROPERTY STRINGS ${_available_features}) ``` 最后一行`set_property(CACHE FEATURES PROPERTY STRINGS ${_available_features})`,當使用`cmake-gui`配置項目,則有有不錯的效果,用戶可根據選擇字段清單,選擇已經定義了的`FEATURES`(參見https://blog.kitware.com/constraining-values-with-comboboxes-in-cmake-cmake-gui/ )。 選項可以放在主`CMakeLists.txt`中,也可以在查詢`ENABLE_NETBEANS`、`ENABLE_CHANNEL`、`ENABLE_TERMINAL`和`FEATURES`的定義附近。前一種策略的優點是,選項列在一個地方,不需要遍歷`CMakeLists.txt`文件來查找選項的定義。因為我們還沒有定義任何目標,所以可以先將選項保存在一個文件中,但是稍后會將選項移到離目標更近的地方,通過本地化作用域,得到可重用的CMake構建塊。 ## 從可執行的目標開始,進行本地化 讓我們添加一些源碼。在Vim示例中,源文件位于`src`下,為了保持主`CMakeLists.txt`的可讀性和可維持性,我們將創建一個新文件`src/CMakeLists.txt`,并將其添加到主`CMakeLists.txt`中,從而可以在自己的目錄范圍內處理該文件: ```cmake add_subdirectory(src) ``` 在`src/CMakeLists.txt`中,可以定義可執行目標,并列出從`build.log`中獲取所有源碼: ```cmake add_executable(vim arabic.c beval.c buffer.c blowfish.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c farsi.c fileio.c fold.c getchar.c hardcopy.c hashtab.c if_cscope.c if_xcmdsrv.c list.c mark.c memline.c menu.c misc1.c misc2.c move.c mbyte.c normal.c ops.c option.c os_unix.c auto/pathdef.c popupmnu.c pty.c quickfix.c regexp.c screen.c search.c sha256.c spell.c spellfile.c syntax.c tag.c term.c terminal.c ui.c undo.c userfunc.c window.c libvterm/src/encoding.c libvterm/src/keyboard.c libvterm/src/mouse.c libvterm/src/parser.c libvterm/src/pen.c libvterm/src/screen.c libvterm/src/state.c libvterm/src/unicode.c libvterm/src/vterm.c netbeans.c channel.c charset.c json.c main.c memfile.c message.c version.c ) ``` 這是一個開始。這種情況下,代碼甚至不會配置,因為源列表包含生成的文件。討論生成文件和鏈接依賴項之前,我們把這一長列表拆分一下,以限制目標依賴項的范圍,并使項目更易于管理。如果我們將它們分組到目標,這將使CMake更容易地找到源文件依賴項,并避免很長的鏈接行。 對于Vim示例,我們可以進一步了解來自`src/Makefile`和`src/configure.ac`的源碼文件進行分組。這些文件中,大多數源文件都是必需的。有些源文件是可選的(`netbeans.c`應該只在`ENABLE_NETBEANS`打開時構建,而`channel.c`應該只在`ENABLE_CHANNEL`打開時構建)。此外,我們可以將所有源代碼分組到`src/libvterm/`下,并使用`ENABLE_TERMINAL`可選地編譯它們。 這樣,我們將CMake結構重組,構成如下的樹結構: ```shell . ├── CMakeLists.txt └── src ├── CMakeLists.txt └── libvterm └── CMakeLists.txt ``` 頂層文件使用`add_subdirectory(src)`添加`src/CMakeLists.txt`。`src/CMakeLists.txt`文件包含三個目標(一個可執行文件和兩個庫),每個目標都帶有編譯定義和包含目錄。首先定義可執行文件: ```cmake add_executable(vim main.c ) target_compile_definitions(vim PRIVATE "HAVE_CONFIG_H" ) ``` 然后,定義一些需要源碼文件的目標: ```cmake add_library(basic_sources "") target_sources(basic_sources PRIVATE arabic.c beval.c blowfish.c buffer.c charset.c crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c farsi.c fileio.c fold.c getchar.c hardcopy.c hashtab.c if_cscope.c if_xcmdsrv.c json.c list.c main.c mark.c memfile.c memline.c menu.c message.c misc1.c misc2.c move.c mbyte.c normal.c ops.c option.c os_unix.c auto/pathdef.c popupmnu.c pty.c quickfix.c regexp.c screen.c search.c sha256.c spell.c spellfile.c syntax.c tag.c term.c terminal.c ui.c undo.c userfunc.c version.c window.c ) target_include_directories(basic_sources PRIVATE ${CMAKE_CURRENT_LIST_DIR}/proto ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) target_compile_definitions(basic_sources PRIVATE "HAVE_CONFIG_H" ) target_link_libraries(vim PUBLIC basic_sources ) ``` 然后,定義一些可選源碼文件的目標: ```cmake add_library(extra_sources "") if(ENABLE_NETBEANS) target_sources(extra_sources PRIVATE netbeans.c ) endif() if(ENABLE_CHANNEL) target_sources(extra_sources PRIVATE channel.c ) endif() target_include_directories(extra_sources PUBLIC ${CMAKE_CURRENT_LIST_DIR}/proto ${CMAKE_CURRENT_BINARY_DIR} ) target_compile_definitions(extra_sources PRIVATE "HAVE_CONFIG_H" ) target_link_libraries(vim PUBLIC extra_sources ) ``` 使用以下代碼,對連接`src/libvterm/`子目錄進行選擇: ```cmake if(ENABLE_TERMINAL) add_subdirectory(libvterm) target_link_libraries(vim PUBLIC libvterm ) endif() ``` 對應的`src/libvterm/CMakeLists.txt`包含以下內容: ```cmake add_library(libvterm "") target_sources(libvterm PRIVATE src/encoding.c src/keyboard.c src/mouse.c src/parser.c src/pen.c src/screen.c src/state.c src/unicode.c src/vterm.c ) target_include_directories(libvterm PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include ) target_compile_definitions(libvterm PRIVATE "HAVE_CONFIG_H" "INLINE=" "VSNPRINTF=vim_vsnprintf" "IS_COMBINING_FUNCTION=utf_iscomposing_uint" "WCWIDTH_FUNCTION=utf_uint2cells" ) ``` 我們已經從`build.log`中獲取了編譯信息。樹結構的優點是,目標的定義靠近源的位置。如果我們決定重構代碼并重命名或移動目錄,描述目標的CMake文件就會隨著源文件一起移動。 我們的示例代碼還沒有配置(除非在成功的Autotools構建之后嘗試配置),現在來試試: ```shell $ mkdir -p build $ cd build $ cmake .. -- The C compiler identification is GNU 8.2.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Configuring done CMake Error at src/CMakeLists.txt:12 (add_library): Cannot find source file: auto/pathdef.c Tried extensions .c .C .c++ .cc .cpp .cxx .cu .m .M .mm .h .hh .h++ .hm .hpp .hxx .in .txx ``` 這里需要生成`auto/pathdef.c`(和其他文件),我們將在下一節中考慮這些文件。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看