<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之旅 廣告
                # 9.2 使用Fortran庫構建C/C++項目 **NOTE**:*此示例代碼可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-9/recipe-02 中找到,其中有一個示例:一個是C++、C和Fortran的混例。該示例在CMake 3.5版(或更高版本)中是有效的,并且已經在GNU/Linux、macOS和Windows上進行過測試。* 第3章第4節,展示了如何檢測Fortran編寫的BLAS和LAPACK線性代數庫,以及如何在C++代碼中使用它們。這里,將重新討論這個方式,但這次的角度有所不同:較少地關注檢測外部庫,會更深入地討論混合C++和Fortran的方面,以及名稱混亂的問題。 ## 準備工作 本示例中,我們將重用第3章第4節源代碼。雖然,我們不會修改源碼或頭文件,但我們會按照第7章“結構化項目”中,討論的建議修改項目樹結構,并得到以下源代碼結構: ```shell . ├── CMakeLists.txt ├── README.md └── src ├── CMakeLists.txt ├── linear-algebra.cpp └── math ├── CMakeLists.txt ├── CxxBLAS.cpp ├── CxxBLAS.hpp ├── CxxLAPACK.cpp └── CxxLAPACK.hpp ``` 這里,收集了BLAS和LAPACK的所有包裝器,它們提供了`src/math`下的數學庫了,主要程序為` linear-algebra.cpp`。因此,所有源都在`src`子目錄下。我們還將CMake代碼分割為三個`CMakeLists.txt`文件,現在來討論這些文件。 ## 具體實施 這個項目混合了C++(作為該示例的主程序語言)和C(封裝Fortran子例程所需的語言)。在根目錄下的`CMakeLists.txt`文件中,我們需要做以下操作: 1. 聲明一個混合語言項目,并選擇C++標準: ```cmake cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(recipe-02 LANGUAGES CXX C Fortran) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) ``` 2. 使用`GNUInstallDirs`模塊來設置CMake將靜態和動態庫,以及可執行文件保存的標準目錄。我們還指示CMake將Fortran編譯的模塊文件放在`modules`目錄下: ```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}) set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/modules) ``` 3. 然后,進入下一個子目錄: ```cmake add_subdirectory(src) ``` 子文件`src/CMakeLists.txt`添加了另一個目錄`math`,其中包含線性代數包裝器。在`src/math/CMakeLists.txt`中,我們需要以下操作: 1. 調用`find_package`來獲取BLAS和LAPACK庫的位置: ```cmake find_package(BLAS REQUIRED) find_package(LAPACK REQUIRED) ``` 2. 包含`FortranCInterface.cmake`模塊,并驗證Fortran、C和C++編譯器是否兼容: ```cmake include(FortranCInterface) FortranCInterface_VERIFY(CXX) ``` 3. 我們還需要生成預處理器宏來處理BLAS和LAPACK子例程的名稱問題。同樣,`FortranCInterface`通過在當前構建目錄中生成一個名為`fc_mangl.h`的頭文件來提供協助: ```cmake FortranCInterface_HEADER( fc_mangle.h MACRO_NAMESPACE "FC_" SYMBOLS DSCAL DGESV ) ``` 4. 接下來,添加了一個庫,其中包含BLAS和LAPACK包裝器的源代碼。我們還指定要找到頭文件和庫的目錄。注意`PUBLIC`屬性,它允許其他依賴于`math`的目標正確地獲得它們的依賴關系: ```cmake add_library(math "") target_sources(math PRIVATE CxxBLAS.cpp CxxLAPACK.cpp ) target_include_directories(math PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) target_link_libraries(math PUBLIC ${LAPACK_LIBRARIES} ) ``` 回到`src/CMakeLists.txt`,我們最終添加了一個可執行目標,并將其鏈接到BLAS/LAPACK包裝器的數學庫: ```cmake add_executable(linear-algebra "") target_sources(linear-algebra PRIVATE linear-algebra.cpp ) target_link_libraries(linear- algebra PRIVATE math ) ``` ## 工作原理 使用`find_package`確定了要鏈接到的庫。方法和之前一樣,需要確保程序能夠正確地調用它們定義的函數。第3章第4節中,我們面臨的問題是編譯器的名稱符號混亂。我們使用`FortranCInterface`模塊來檢查所選的C和C++編譯器與Fortran編譯器的兼容性。我們還使用`FortranCInterface_HEADER`函數生成帶有宏的頭文件,以處理Fortran子例程的名稱混亂。并通過以下代碼實現: ```cmake FortranCInterface_HEADER( fc_mangle.h MACRO_NAMESPACE "FC_" SYMBOLS DSCAL DGESV ) ``` 這個命令將生成`fc_mangl.h`頭文件,其中包含從Fortran編譯器推斷的名稱混亂宏,并將其保存到當前二進制目錄`CMAKE_CURRENT_BINARY_DIR`中。我們小心地將`CMAKE_CURRENT_BINARY_DIR`設置為數學目標的包含路徑。生成的`fc_mangle.h`如下: ```c++ #ifndef FC_HEADER_INCLUDED #define FC_HEADER_INCLUDED /* Mangling for Fortran global symbols without underscores. */ #define FC_GLOBAL(name,NAME) name##_ /* Mangling for Fortran global symbols with underscores. */ #define FC_GLOBAL_(name,NAME) name##_ /* Mangling for Fortran module symbols without underscores. */ #define FC_MODULE(mod_name,name, mod_NAME,NAME) __##mod_name##_MOD_##name /* Mangling for Fortran module symbols with underscores. */ #define FC_MODULE_(mod_name,name, mod_NAME,NAME) __##mod_name##_MOD_##name /* Mangle some symbols automatically. */ #define DSCAL FC_GLOBAL(dscal, DSCAL) #define DGESV FC_GLOBAL(dgesv, DGESV) #endif ``` 本例中的編譯器使用下劃線進行錯誤處理。由于Fortran不區分大小寫,子例程可能以小寫或大寫出現,這就說明將這兩種情況傳遞給宏的必要性。注意,CMake還將為隱藏在Fortran模塊后面的符號生成宏。 **NOTE**:*現在,BLAS和LAPACK的許多實現都在Fortran子例程附帶了一個C的包裝層。這些包裝器已經標準化,分別稱為CBLAS和LAPACKE。* 由于已經將源組織成庫目標和可執行目標,所以我們應該對目標的`PUBLIC`、`INTERFACE`和`PRIVATE`可見性屬性的使用進行評論。與源文件一樣,包括目錄、編譯定義和選項,當與`target_link_libraries`一起使用時,這些屬性的含義是相同的: * 使用`PRIVATE`屬性,庫將只鏈接到當前目標,而不鏈接到使用它的任何其他目標。 * 使用`INTERFACE`屬性,庫將只鏈接到使用當前目標作為依賴項的目標。 * 使用`PUBLIC`屬性,庫將被鏈接到當前目標,以及將其作為依賴項使用的任何其他目標。
                  <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>

                              哎呀哎呀视频在线观看