<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.2 生成文件并編寫平臺檢查 對于Vim示例,我們需要在配置時生成三個文件,`src/auto/pathdef.c`、`src/auto/config.h`和`src/auto/osdef.h`: * pathdef.c:記錄安裝路徑、編譯/鏈接標志、當前用戶和主機名 * config.h:編譯系統的環境 * osdef.h:由`src/osdef.sh`生成的文件 這種情況相當普遍。需要CMake配置文件,配置時執行一個腳本,執行許多平臺檢查命令,來生成`config.h`。特別是,對于那些可移植的項目,平臺檢查非常普遍。 在原始目錄樹中,文件在`src`文件夾下生成。而我們將使用不同的方法:這些文件會生成在`build`目錄中。這樣做的原因是生成的文件通常依賴于所選擇的選項、編譯器或構建類型,我們希望保持同一個源,可以適配多個構建。要在`build`目錄中啟用生成,我們必須對生成文件的腳本進行改動。 ## 構造文件 我們將把與生成文件相關的函數集中放在`src/autogenerate.cmake `中。在定義可執行目標之前,在`src/CMakeLists.txt`中調用這些函數: ```cmake # generate config.h, pathdef.c, and osdef.h include(autogenerate.cmake) generate_config_h() generate_pathdef_c() generate_osdef_h() add_executable(vim main.c ) # ... ``` `src/autogenerate.cmake`中包含了其他檢測頭文件、函數和庫等幾個函數: ```cmake include(CheckTypeSize) include(CheckFunctionExists) include(CheckIncludeFiles) include(CheckLibraryExists) include(CheckCSourceCompiles) function(generate_config_h) # ... to be written endfunction() function(generate_pathdef_c) # ... to be written endfunction() function(generate_osdef_h) # ... to be written endfunction() ``` 我們選擇了一些用于生成文件的函數,而不是用宏或“裸”CMake代碼。在前幾章中討論過的,這是避免了一些問題: * 避免多次生成文件,以防多次包含模塊。我們可以使用一個包含保護來防止意外地多次運行代碼。 * 保證了對函數中變量范圍的完全控制。這避免了這些定義溢出,從而出現變量污染的情況。 ## 根據系統配置預處理宏定義 `config.h`文件以`src/config.h.in`為目標所生成的,其中包含根據系統功能配置的預處理標志: ```c++ /* Define if we have EBCDIC code */ #undef EBCDIC /* Define unless no X support found */ #undef HAVE_X11 /* Define when terminfo support found */ #undef TERMINFO /* Define when termcap.h contains ospeed */ #undef HAVE_OSPEED /* ... */ ``` 生成的`src/config.h`示例類似如下情況(定義可以根據環境的不同而不同): ```c++ /* Define if we have EBCDIC code */ /* #undef EBCDIC */ /* Define unless no X support found */ #define HAVE_X11 1 /* Define when terminfo support found */ #define TERMINFO 1 /* Define when termcap.h contains ospeed */ /* #undef HAVE_OSPEED */ /* ... */ ``` 這個頁面是一個很好的平臺檢查示例: https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/How-To-Write-Platform-Checks 在`src/configure.ac`中,我們可以檢查需要執行哪些平臺檢查,從而來設置相應的預處理定義。 我們將使用`#cmakedefine`(https://cmake.org/cmake/help/v3.5/command/configure_file.html?highlight=cmakedefine )為了確保不破壞現有的Autotools構建,我們將復制` config.h.in `為`config.h.cmake.in`,并將所有`#undef SOME_DEFINITION`更改為`#cmakedefine SOME_DEFINITION @SOME_DEFINITION@`。 在`generate_config_h`函數中,先定義兩個變量: ```cmake set(TERMINFO 1) set(UNIX 1) # this is hardcoded to keep the discussion in the book chapter # which describes the migration to CMake simpler set(TIME_WITH_SYS_TIME 1) set(RETSIGTYPE void) set(SIGRETURN return) find_package(X11) set(HAVE_X11 ${X11_FOUND}) ``` 然后,我們執行幾個類型檢查: ```cmake check_type_size("int" VIM_SIZEOF_INT) check_type_size("long" VIM_SIZEOF_LONG) check_type_size("time_t" SIZEOF_TIME_T) check_type_size("off_t" SIZEOF_OFF_T) ``` 然后,我們對函數進行循環,檢查系統是否能夠解析: ```cmake foreach( _function IN ITEMS fchdir fchown fchmod fsync getcwd getpseudotty getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memset mkdtemp nanosleep opendir putenv qsort readlink select setenv getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp strnicmp strpbrk strtol towlower towupper iswupper usleep utime utimes mblen ftruncate ) string(TOUPPER "${_function}" _function_uppercase) check_function_exists(${_function} HAVE_${_function_uppercase}) endforeach() ``` 驗證庫是否包含特定函數: ```cmake check_library_exists(tinfo tgetent "" HAVE_TGETENT) if(NOT HAVE_TGETENT) message(FATAL_ERROR "Could not find the tgetent() function. You need to install a terminal library; for example ncurses.") endif() ``` 然后,我們循環頭文件,檢查它們是否可用: ```cmake foreach( _header IN ITEMS setjmp.h dirent.h stdint.h stdlib.h string.h sys/select.h sys/utsname.h termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h sys/types.h termio.h iconv.h inttypes.h langinfo.h math.h unistd.h stropts.h errno.h sys/resource.h sys/systeminfo.h locale.h sys/stream.h termios.h libc.h sys/statfs.h poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h libgen.h util/debug.h util/msg18n.h frame.h sys/acl.h sys/access.h sys/sysinfo.h wchar.h wctype.h ) string(TOUPPER "${_header}" _header_uppercase) string(REPLACE "/" "_" _header_normalized "${_header_uppercase}") string(REPLACE "." "_" _header_normalized "${_header_normalized}") check_include_files(${_header} HAVE_${_header_normalized}) endforeach() ``` 然后,我們將CMake選項從轉換為預處理定義: ```cmake string(TOUPPER "${FEATURES}" _features_upper) set(FEAT_${_features_upper} 1) set(FEAT_NETBEANS_INTG ${ENABLE_NETBEANS}) set(FEAT_JOB_CHANNEL ${ENABLE_CHANNEL}) set(FEAT_TERMINAL ${ENABLE_TERMINAL}) ``` 最后,我們檢查是否能夠編譯一個特定的代碼片段: ```cmake check_c_source_compiles( " #include <sys/types.h> #include <sys/stat.h> int main () { struct stat st; int n; stat(\"/\", &st); n = (int)st.st_blksize; ; return 0; } " HAVE_ST_BLKSIZE ) ``` 然后,使用定義的變量配置`src/config.h.cmake.in`生成`config.h`,其中包含`generate_config_h`函數: ```cmake configure_file( ${CMAKE_CURRENT_LIST_DIR}/config.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/auto/config.h @ONLY ) ``` ## 使用路徑和編譯器標志配置文件 從` src/pathdef.c.in `生成` pathdef.c`: ```c++ #include "vim.h" char_u *default_vim_dir = (char_u *)"@_default_vim_dir@"; char_u *default_vimruntime_dir = (char_u *)"@_default_vimruntime_dir@"; char_u *all_cflags = (char_u *)"@_all_cflags@"; char_u *all_lflags = (char_u *)"@_all_lflags@"; char_u *compiled_user = (char_u *)"@_compiled_user@"; char_u *compiled_sys = (char_u *)"@_compiled_sys@"; ``` `generate_pathdef_c`函數在`src/pathdef.c.in`進行配置。為了簡單起見,我們省略了鏈接標志: ```cmake function(generate_pathdef_c) set(_default_vim_dir ${CMAKE_INSTALL_PREFIX}) set(_default_vimruntime_dir ${_default_vim_dir}) set(_all_cflags "${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS}") if(CMAKE_BUILD_TYPE STREQUAL "Release") set(_all_cflags "${_all_cflags} ${CMAKE_C_FLAGS_RELEASE}") else() set(_all_cflags "${_all_cflags} ${CMAKE_C_FLAGS_DEBUG}") endif() # it would require a bit more work and execute commands at build time # to get the link line into the binary set(_all_lflags "undefined") if(WIN32) set(_compiled_user $ENV{USERNAME}) else() set(_compiled_user $ENV{USER}) endif() cmake_host_system_information(RESULT _compiled_sys QUERY HOSTNAME) configure_file( ${CMAKE_CURRENT_LIST_DIR}/pathdef.c.in ${CMAKE_CURRENT_BINARY_DIR}/auto/pathdef.c @ONLY ) endfunction() ``` ## 配置時執行shell腳本 最后,我們使用以下函數生成`osdef.h`: ```cmake function(generate_osdef_h) find_program(BASH_EXECUTABLE bash) execute_process( COMMAND ${BASH_EXECUTABLE} osdef.sh ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} ) endfunction() ``` 為了在`${CMAKE_CURRENT_BINARY_DIR}/src/auto`而不是`src/auto`中生成`osdef.h`,我們必須調整`osdef.sh`以接受`${CMAKE_CURRENT_BINARY_DIR}`作為命令行參數。 `osdef.sh`中,我們會檢查是否給定了這個參數: ```shell if [ $# -eq 0 ] then # there are no arguments # assume the target directory is current directory target_directory=$PWD else # target directory is provided as argument target_directory=$1 fi ``` 然后,生成`${target_directory}/auto/osdef.h`。為此,我們還必須在`osdef.sh`中調整以下行: ```shell $CC -I. -I$srcdir - I${target_directory} -E osdef0.c >osdef0.cc ```
                  <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>

                              哎呀哎呀视频在线观看