<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 6.2 使用Python在配置時生成源碼 **NOTE**:*此示例代碼可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-6/recipe-02 中找到,其中包含一個Fortran/C例子。該示例在CMake 3.10版(或更高版本)中是有效的,并且已經在GNU/Linux、macOS和Windows(使用MSYS Makefile)上進行過測試。* 本示例中,我們將再次從模板`print_info.c.in`生成`print_info.c`。但這一次,將假設CMake函數`configure_file()`沒有創建源文件,然后使用Python腳本模擬這個過程。當然,對于實際的項目,我們可能更傾向于使用`configure_file()`,但有時使用Python生成源代碼的需要時,我們也應該知道如何應對。 這個示例有嚴重的限制,不能完全模擬`configure_file()`。我們在這里介紹的方法,不能生成一個自動依賴項,該依賴項將在構建時重新生成`print_info.c`。換句話說,如果在配置之后刪除生成的`print_info.c`,則不會重新生成該文件,構建也會失敗。要正確地模擬`configure_file()`,需要使用`add_custom_command()`和`add_custom_target()`。我們將在第3節中使用它們,來克服這個限制。 這個示例中,我們將使用一個簡單的Python腳本。這個腳本將讀取`print_info.c.in`。用從CMake傳遞給Python腳本的參數替換文件中的占位符。對于更復雜的模板,我們建議使用外部工具,比如Jinja(參見http://jinja.pocoo.org )。 ```python def configure_file(input_file, output_file, vars_dict): with input_file.open('r') as f: template = f.read() for var in vars_dict: template = template.replace('@' + var + '@', vars_dict[var]) with output_file.open('w') as f: f.write(template) ``` 這個函數讀取一個輸入文件,遍歷` vars_dict`變量中的目錄,并用對應的值替換`@key@`,再將結果寫入輸出文件。這里的鍵值對,將由CMake提供。 ## 準備工作 `print_info.c.in`和`example.f90`與之前的示例相同。此外,我們將使用Python腳本`configurator.py`,它提供了一個函數: ```python def configure_file(input_file, output_file, vars_dict): with input_file.open('r') as f: template = f.read() for var in vars_dict: template = template.replace('@' + var + '@', vars_dict[var]) with output_file.open('w') as f: f.write(template) ``` 該函數讀取輸入文件,遍歷`vars_dict`字典的所有鍵,用對應的值替換模式`@key@`,并將結果寫入輸出文件(鍵值由CMake提供)。 ## 具體實施 與前面的示例類似,我們需要配置一個模板文件,但這一次,使用Python腳本模擬`configure_file()`函數。我們保持CMakeLists.txt基本不變,并提供一組命令進行替換操作`configure_file(print_info.c.in print_info.c @ONLY)`,接下來將逐步介紹這些命令: 1. 首先,構造一個變量`_config_script`,它將包含一個Python腳本,稍后我們將執行這個腳本: ```cmake set(_config_script " from pathlib import Path source_dir = Path('${CMAKE_CURRENT_SOURCE_DIR}') binary_dir = Path('${CMAKE_CURRENT_BINARY_DIR}') input_file = source_dir / 'print_info.c.in' output_file = binary_dir / 'print_info.c' import sys sys.path.insert(0, str(source_dir)) from configurator import configure_file vars_dict = { '_user_name': '${_user_name}', '_host_name': '${_host_name}', '_fqdn': '${_fqdn}', '_processor_name': '${_processor_name}', '_processor_description': '${_processor_description}', '_os_name': '${_os_name}', '_os_release': '${_os_release}', '_os_version': '${_os_version}', '_os_platform': '${_os_platform}', '_configuration_time': '${_configuration_time}', 'CMAKE_VERSION': '${CMAKE_VERSION}', 'CMAKE_GENERATOR': '${CMAKE_GENERATOR}', 'CMAKE_Fortran_COMPILER': '${CMAKE_Fortran_COMPILER}', 'CMAKE_C_COMPILER': '${CMAKE_C_COMPILER}', } configure_file(input_file, output_file, vars_dict) ") ``` 2. 使用`find_package`讓CMake使用Python解釋器: ```cmake find_package(PythonInterp QUIET REQUIRED) ``` 3. 如果找到Python解釋器,則可以在CMake中執行`_config_script`,并生成`print_info.c`文件: ```cmake execute_process( COMMAND ${PYTHON_EXECUTABLE} "-c" ${_config_script} ) ``` 4. 之后,定義可執行目標和依賴項,這與前一個示例相同。所以,得到的輸出沒有變化。 ## 工作原理 回顧一下對CMakeLists.txt的更改。 我們執行了一個Python腳本生成`print_info.c`。運行Python腳本前,首先檢測Python解釋器,并構造Python腳本。Python腳本導入`configure_file`函數,我們在`configurator.py`中定義了這個函數。為它提供用于讀寫的文件位置,并將其值作為鍵值對。 此示例展示了生成配置的另一種方法,將生成任務委托給外部腳本,可以將配置報告編譯成可執行文件,甚至庫目標。我們在前面的配置中認為的第一種方法更簡潔,但是使用本示例中提供的方法,我們可以靈活地使用Python(或其他語言),實現任何在配置時間所需的步驟。使用當前方法,我們可以通過腳本的方式執行類似`cmake_host_system_information()`的操作。 但要記住,這種方法也有其局限性,它不能在構建時重新生成`print_info.c`的自動依賴項。下一個示例中,我們應對這個挑戰。 ## 更多信息 我們可以使用`get_cmake_property(_vars VARIABLES)`來獲得所有變量的列表,而不是顯式地構造`vars_dict`(這感覺有點重復),并且可以遍歷`_vars`的所有元素來訪問它們的值: ```cmake get_cmake_property(_vars VARIABLES) foreach(_var IN ITEMS ${_vars}) message("variable ${_var} has the value ${${_var}}") endforeach() ``` 使用這種方法,可以隱式地構建`vars_dict`。但是,必須注意轉義包含字符的值,例如:`;`, Python會將其解析為一條指令的末尾。
                  <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>

                              哎呀哎呀视频在线观看