<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國際加速解決方案。 廣告
                # 9.1 使用C/C++庫構建Fortran項目 **NOTE**:*此示例代碼可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-9/recipe-01 中找到,其中有兩個示例:一個是Fortran與C的混例,另一個是Fortran和C++的混例。該示例在CMake 3.5版(或更高版本)中是有效的,并且已經在GNU/Linux、macOS和Windows上進行過測試。* Fortran作為高性能計算語言有著悠久的歷史。目前,許多線性代數庫仍然使用Fortran語言編寫,許多大型的數字處理包也保持與過去幾十年的代碼兼容。而Fortran提出了一個很自然的語法處理數值數組,它缺乏與操作系統交互,所以為了編程的通用性,需要一個互操作性層(使用C實現),才發布了Fortran 2003標準。本示例將展示如何用C系統庫和自定義C代碼來對接Fortran代碼。 ## 準備工作 第7章中,我們把項目結構列為一個樹。每個子目錄都有一個`CMakeLists.txt`文件,其中包含與該目錄相關的指令。這使我們可以對子目錄進行限制中,如這個例子: ```shell . ├── CMakeLists.txt └── src ├── bt-randomgen-example.f90 ├── CMakeLists.txt ├── interfaces │ ├── CMakeLists.txt │ ├── interface_backtrace.f90 │ ├── interface_randomgen.f90 │ └── randomgen.c └── utils ├── CMakeLists.txt └── util_strings.f90 ``` 我們的例子中,`src`子目錄中包括`bt-randomgen-example.f90`,會將源碼編譯成可執行文件。另外兩個子目錄`interface`和`utils`包含更多的源代碼,這些源代碼將被編譯成庫。 `interfaces`子目錄中的源代碼展示了如何包裝向后追蹤的C系統庫。例如,`interface_backtrace.f90 `: ```fortran module interface_backtrace implicit none interface function backtrace(buffer, size) result(bt) bind(C, name="backtrace") use, intrinsic :: iso_c_binding, only: c_int, c_ptr type(c_ptr) :: buffer integer(c_int), value :: size integer(c_int) :: bt end function subroutine backtrace_symbols_fd(buffer, size, fd) bind(C, name="backtrace_symbols_fd") use, intrinsic :: iso_c_binding, only: c_int, c_ptr type(c_ptr) :: buffer integer(c_int), value :: size, fd end subroutine end interface end module ``` 上面的例子演示了: * 內置`iso_c_binding`模塊,確保Fortran和C類型和函數的互操作性。 * `interface`聲明,將函數在單獨庫中綁定到相應的符號上。 * `bind(C)`屬性,為聲明的函數進行命名修飾。 這個子目錄還包含兩個源文件: * randomgen.c:這是一個C源文件,它對外公開了一個函數,使用C標準`rand`函數在一個區間內生成隨機整數。 * interface_randomgen.f90:它將C函數封裝在Fortran可執行文件中使用。 ## 具體實施 我們有4個`CMakeLists.txt`實例要查看——根目錄下1個,子目錄下3個。讓我們從根目錄的`CMakeLists.txt`開始: 1. 聲明一個Fortran和C的混合語言項目: ```cmake cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(recipe-01 LANGUAGES Fortran C) ``` 2. CMake將靜態庫和動態庫保存在`build`目錄下的`lib`目錄中。可執行文件保存在`bin`目錄下,Fortran編譯模塊文件保存在`modules`目錄下: ```cmake set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/modules) ``` 3. 接下來,我們進入第一個子`CMakeLists.txt`,添加`src`子目錄: ```cmake add_subdirectory(src) ``` 4. `src/CMakeLists.txt`文件添加了兩個子目錄: ```cmake add_subdirectory(interfaces) add_subdirectory(utils) ``` 在`interfaces`子目錄中,我們將執行以下操作: 1. 包括` FortranCInterface.cmak`模塊,并驗證C和Fortran編譯器可以正確地交互: ```cmake include(FortranCInterface) FortranCInterface_VERIFY() ``` 2. 接下來,我們找到Backtrace系統庫,因為我們想在Fortran代碼中使用它: ```cmake find_package(Backtrace REQUIRED) ``` 3. 然后,創建一個共享庫目標,其中包含Backtrace包裝器、隨機數生成器,以及Fortran包裝器的源文件: ```cmake add_library(bt-randomgen-wrap SHARED "") target_sources(bt-randomgen-wrap PRIVATE interface_backtrace.f90 interface_randomgen.f90 randomgen.c ) ``` 4. 我們還為新生成的庫目標設置了鏈接庫。使用`PUBLIC`屬性,以便連接到其他目標時,能正確地看到依賴關系: ```cmake target_link_libraries(bt-randomgen-wrap PUBLIC ${Backtrace_LIBRARIES} ) ``` `utils`子目錄中,還有一個`CMakeLists.txt`,其只有一單行程序:我們創建一個新的庫目標,子目錄中的源文件將被編譯到這個目標庫中。并與這個目標沒有依賴關系: ```cmake add_library(utils SHARED util_strings.f90) ``` 回到`src/CMakeLists.txt`: 1. 使用` bt-randomgen-example.f90 `添加一個可執行目標: ```cmake add_executable(bt-randomgen-example bt-randomgen-example.f90) ``` 2. 最后,將在子`CMakeLists.txt`中生成的庫目標,并鏈接到可執行目標: ```cmake target_link_libraries(bt-randomgen-example PRIVATE bt-randomgen-wrap utils ) ``` ## 工作原理 確定鏈接了正確庫之后,需要保證程序能夠正確調用函數。每個編譯器在生成機器碼時都會執行命名檢查。不過,這種操作的約定不是通用的,而是與編譯器相關的。`FortranCInterface`,我們已經在第3章第4節時,檢查所選C編譯器與Fortran編譯器的兼容性。對于當前的目的,命名檢查并不是一個真正的問題。Fortran 2003標準提供了可選`name`參數的函數和子例程定義了`bind`屬性。如果提供了這個參數,編譯器將使用程序員指定的名稱為這些子例程和函數生成符號。例如,backtrace函數可以從C語言中暴露給Fortran,并保留其命名: ```cmake function backtrace(buffer, size) result(bt) bind(C, name="backtrace") ``` ## 更多信息 `interface/CMakeLists.txt`中的CMake代碼還表明,可以使用不同語言的源文件創建庫。CMake能夠做到以下幾點: * 列出的源文件中獲取目標文件,并識別要使用哪個編譯器。 * 選擇適當的鏈接器,以便構建庫(或可執行文件)。 CMake如何決定使用哪個編譯器?在`project`命令時使用參數`LANGUAGES`指定,這樣CMake會檢查系統上給定語言編譯器。當使用源文件列表添加目標時,CMake將根據文件擴展名選擇適當地編譯器。因此,以`.c`結尾的文件使用C編譯器編譯,而以`.f90`結尾的文件(如果需要預處理,可以使用`.F90`)將使用Fortran編譯器編譯。類似地,對于C++, `.cpp`或`.cxx`擴展將觸發`C++`編譯器。我們只列出了C/C++和Fortran語言的一些可能的、有效的文件擴展名,但是CMake可以識別更多的擴展名。如果您的項目中的文件擴展名,由于某種原因不在可識別的擴展名之列,該怎么辦?源文件屬性可以用來告訴CMake在特定的源文件上使用哪個編譯器,就像這樣: ```cmake set_source_files_properties(my_source_file.axx PROPERTIES LANGUAGE CXX ) ``` 那鏈接器呢?CMake如何確定目標的鏈接器語言?對于不混合編程語言的目標很簡單:通過生成目標文件的編譯器命令調用鏈接器即可。如果目標混合了多個語言,就像示例中一樣,則根據在語言混合中,優先級最高的語言來選擇鏈接器語言。比如,我們的示例中混合了Fortran和C,因此Fortran語言比C語言具有更高的優先級,因此使用Fortran用作鏈接器語言。當混合使用Fortran和C++時,后者具有更高的優先級,因此C++被用作鏈接器語言。就像編譯器語言一樣,我們可以通過目標相應的`LINKER_LANGUAGE`屬性,強制CMake為我們的目標使用特定的鏈接器語言: ```cmake set_target_properties(my_target PROPERTIES LINKER_LANGUAGE Fortran ) ```
                  <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>

                              哎呀哎呀视频在线观看