diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2e586d98..efad5e87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -140,7 +140,17 @@ jobs: cmake .. -DCMAKE_INSTALL_PREFIX=../install \ -DCMAKE_BUILD_TYPE=Release \ -DT8CODE_ROOT=$PWD/../t8code-local/prefix \ - -DENABLE_TESTING=ON -DJULIA_PROJECT_PATH=../libtrixi-julia + -DLIBTRIXI_ENABLE_TESTING=ON -DJULIA_PROJECT_PATH=../libtrixi-julia + + - name: Configure without Fortran (test_type == 'regular') + if: ${{ matrix.test_type == 'regular' }} + run: | + mkdir build-nofortran + cd build-nofortran + cmake .. -DCMAKE_INSTALL_PREFIX=../install-nofortran \ + -DCMAKE_BUILD_TYPE=Release \ + -DT8CODE_ROOT=$PWD/../t8code-local/prefix \ + -DLIBTRIXI_BUILD_FORTRAN_API=OFF - name: Configure (test_type == 'coverage') if: ${{ matrix.test_type == 'coverage' }} @@ -154,7 +164,7 @@ jobs: -DCMAKE_Fortran_FLAGS="-cpp --coverage -O0" \ -DCMAKE_EXE_LINKER_FLAGS="--coverage" \ -DCMAKE_SHARED_LINKER_FLAGS="--coverage" \ - -DENABLE_TESTING=ON -DJULIA_PROJECT_PATH=../libtrixi-julia + -DLIBTRIXI_ENABLE_TESTING=ON -DJULIA_PROJECT_PATH=../libtrixi-julia - name: Build if: ${{ matrix.test_type == 'regular' || matrix.test_type == 'coverage' || matrix.test_type == 'smoke' }} @@ -162,6 +172,12 @@ jobs: cd build make -j 2 + - name: Build without Fortran + if: ${{ matrix.test_type == 'regular' }} + run: | + cd build-nofortran + make -j 2 + - name: Install if: ${{ matrix.test_type == 'regular' || matrix.test_type == 'coverage' || matrix.test_type == 'smoke' }} run: | @@ -227,7 +243,7 @@ jobs: cmake .. -DCMAKE_INSTALL_PREFIX=../install \ -DCMAKE_BUILD_TYPE=Debug \ -DT8CODE_ROOT=$PWD/../t8code-local/prefix \ - -DUSE_PACKAGE_COMPILER=ON \ + -DLIBTRIXI_USE_PACKAGE_COMPILER=ON \ -DJULIA_PROJECT_PATH=$PWD/../libtrixi-julia - name: Build (test_type == 'package-compiler') @@ -300,6 +316,16 @@ jobs: env: LIBTRIXI_DEBUG: all + - name: Run C example (Fortran API disabled) + if: ${{ matrix.test_type == 'regular'}} + run: | + cd build-nofortran/examples + mpirun -n 2 trixi_controller_simple_c \ + ../../libtrixi-julia \ + ../../LibTrixi.jl/examples/libelixir_p4est2d_euler_sedov.jl + env: + LIBTRIXI_DEBUG: all + - name: Check error handling of examples if: ${{ matrix.test_type == 'regular' || matrix.test_type == 'coverage' }} run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 5376e94d..2e55aec9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ # Specify the minimum version # 3.9 required for regex submatches # 3.12 required for policy CMP0074 (using *_ROOT variables) -cmake_minimum_required ( VERSION 3.12 ) +# 3.13 required for policy CMP0076 (target_sources() command converts relative paths to absolute) +cmake_minimum_required ( VERSION 3.13 ) # Reconfigure if Project.toml has changed set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/LibTrixi.jl/Project.toml") @@ -23,8 +24,18 @@ file(WRITE "${CMAKE_BINARY_DIR}/LIBTRIXI_VERSION" "${LIBTRIXI_VERSION}\n") project ( trixi VERSION ${LIBTRIXI_VERSION_MAJOR}.${LIBTRIXI_VERSION_MINOR}.${LIBTRIXI_VERSION_PATCH} DESCRIPTION "Interface library for using Trixi.jl from C/C++/Fortran" ) -# Enable C and Fortran -enable_language(C Fortran) +# Additional configuration options +option( LIBTRIXI_BUILD_FORTRAN_API "Enable the build of the Fortran interface" ON ) +option( LIBTRIXI_ENABLE_TESTING "Build tests using Google Test (C) and test-drive (Fortran)" OFF ) +option( LIBTRIXI_USE_PACKAGE_COMPILER "Build standalone libtrixi.so using PackageCompiler.jl" ) + +# Enable C always +enable_language( C ) + +# Optionally enable Fortran +if( LIBTRIXI_BUILD_FORTRAN_API ) + enable_language( Fortran ) +endif() # Enabling setting rpath for installation SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) @@ -47,8 +58,7 @@ endif() find_package( MPI REQUIRED ) # Find Google Test and test-drive on demand -option( ENABLE_TESTING "Build tests using Google Test (C) and test-drive (Fortran)" ) -if( ENABLE_TESTING ) +if( LIBTRIXI_ENABLE_TESTING ) if ( NOT DEFINED JULIA_PROJECT_PATH ) message( FATAL_ERROR "JULIA_PROJECT_PATH not set, tests will not work.") endif() @@ -57,22 +67,23 @@ if( ENABLE_TESTING ) find_package( GTest REQUIRED ) - set ( TEST_DRIVE_FIND_METHOD fetch ) - # Option TEST_DRIVE_BUILD_TESTING is hard-coded to ON, could be spared - find_package( test-drive REQUIRED ) + if( LIBTRIXI_BUILD_FORTRAN_API ) + set ( TEST_DRIVE_FIND_METHOD fetch ) + # Option TEST_DRIVE_BUILD_TESTING is hard-coded to ON, could be spared + find_package( test-drive REQUIRED ) + endif() endif() -# Optionally use PackageCompiler.jl to build standalone libtrixi.so -option( USE_PACKAGE_COMPILER "Build standalone libtrixi.so using PackageCompiler.jl" ) - -# Fortran mod file location -set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}) +if( LIBTRIXI_BUILD_FORTRAN_API ) + # Fortran mod file location + set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}) +endif() -if( USE_PACKAGE_COMPILER ) +if( LIBTRIXI_USE_PACKAGE_COMPILER ) if ( NOT DEFINED JULIA_PROJECT_PATH ) message( FATAL_ERROR "JULIA_PROJECT_PATH needs to be set for PackageCompiler.jl.") endif() - if ( ENABLE_TESTING ) + if ( LIBTRIXI_ENABLE_TESTING ) message( NOTICE "Testing is not supported when PackageCompiler is used.") endif() @@ -89,10 +100,12 @@ if( USE_PACKAGE_COMPILER ) COMMAND ${CMAKE_COMMAND} -E copy ${PC_INIT_SOURCE} ${PC_INIT_BUILD} DEPENDS ${PC_INIT_SOURCE} ) - # Add a library target (libtrixi), only for Fortran module - add_library( ${PROJECT_NAME} OBJECT - src/api.f90 - ) + if( LIBTRIXI_BUILD_FORTRAN_API ) + # Add a library target (libtrixi), only for Fortran module + add_library( ${PROJECT_NAME} OBJECT + src/api.f90 + ) + endif() # Custom command to run PackageCompiler.jl to produce libtrixi.so add_custom_command( OUTPUT ${PC_LIBTRIXI_SO} @@ -123,12 +136,18 @@ else() # Library target add_library ( ${PROJECT_NAME} SHARED src/api.c - src/api.f90 src/auxiliary.h src/auxiliary.c src/trixi.h ) + # Build Fortran library target on demand + if( LIBTRIXI_BUILD_FORTRAN_API ) + target_sources (${PROJECT_NAME} PRIVATE + src/api.f90 + ) + endif() + # Include directories, private target_include_directories ( ${PROJECT_NAME} PRIVATE src ) @@ -141,7 +160,10 @@ else() # Include directories - target_include_directories( ${PROJECT_NAME} PRIVATE src ${JULIA_INCLUDE_DIRS} ) + # PRIVATE: Do not include internal directory in projects building against libtrixi + # SYSTEM: Disable warnings/error from upstream libraries + target_include_directories( ${PROJECT_NAME} PRIVATE src ) + target_include_directories( ${PROJECT_NAME} SYSTEM PRIVATE ${JULIA_INCLUDE_DIRS} ) # Libraries to link target_link_libraries( ${PROJECT_NAME} PRIVATE ${JULIA_LIBRARY} ) @@ -160,13 +182,15 @@ else() add_library ( ${PROJECT_NAME}_tls OBJECT src/tls.c ) - target_include_directories( ${PROJECT_NAME}_tls PRIVATE ${JULIA_INCLUDE_DIRS} ) + target_include_directories( ${PROJECT_NAME}_tls SYSTEM PRIVATE ${JULIA_INCLUDE_DIRS} ) # Add test on demand - if( ENABLE_TESTING ) + if( LIBTRIXI_ENABLE_TESTING ) enable_testing() add_subdirectory( test/c ) - add_subdirectory( test/fortran ) + if( LIBTRIXI_BUILD_FORTRAN_API ) + add_subdirectory( test/fortran ) + endif() endif() @@ -183,7 +207,9 @@ set_target_properties ( ${PROJECT_NAME} PROPERTIES PUBLIC_HEADER src/trixi.h ) # Common install configuration install( TARGETS ${PROJECT_NAME} ) install( DIRECTORY LibTrixi.jl DESTINATION share/libtrixi PATTERN "lib" EXCLUDE ) -install( FILES ${CMAKE_Fortran_MODULE_DIRECTORY}/libtrixi.mod TYPE INCLUDE) +if( LIBTRIXI_BUILD_FORTRAN_API ) + install( FILES ${CMAKE_Fortran_MODULE_DIRECTORY}/libtrixi.mod TYPE INCLUDE) +endif() install( PROGRAMS utils/libtrixi-init-julia TYPE BIN ) # Add examples diff --git a/README.md b/README.md index cc57ae01..117acb1f 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,8 @@ For building, `cmake` and its typical workflow is used. - Specifying the directory `install_directory` for later installation is optional. - Optional specification of build type sets some default compiler options for optimized or debug code. + - By default the Fortran-Interface is built; it may be excluded with + `-DLIBTRIXI_BUILD_FORTRAN_API=OFF`. - Building with t8code support is optional. It requires to pass `-DT8CODE_ROOT=`. @@ -302,7 +304,7 @@ To try this out, perform the following steps: *using cmake* - Add ``` - -DUSE_PACKAGE_COMPILER=ON -DJULIA_PROJECT_PATH= + -DLIBTRIXI_USE_PACKAGE_COMPILER=ON -DJULIA_PROJECT_PATH= ``` to your cmake call (see above) 3. From inside the `examples` folder you should be able to run the example (in parallel) diff --git a/docs/src/developers.md b/docs/src/developers.md index 0f6834c3..5ddd05f0 100644 --- a/docs/src/developers.md +++ b/docs/src/developers.md @@ -50,7 +50,7 @@ For testing the C interface of libtrixi we rely on [GoogleTest](https://google.g The tests are contained in `cpp`-files located under `test/c`. They are processed by `cmake` and made available via `ctest`, provided the options ``` --DENABLE_TESTING=ON -DJULIA_PROJECT_PATH= +-DLIBTRIXI_ENABLE_TESTING=ON -DJULIA_PROJECT_PATH= ``` are passed to `cmake` during configuration. The executables can then be found under `/test/c` (they will not be installed). To run them, execute diff --git a/docs/src/index.md b/docs/src/index.md index 5ad8376b..48baaa86 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -56,6 +56,8 @@ For building, `cmake` and its typical workflow is used. - Specifying the directory `install_directory` for later installation is optional. - Optional specification of build type sets some default compiler options for optimized or debug code. + - By default the Fortran-Interface is built; it may be excluded with + `-DLIBTRIXI_BUILD_FORTRAN_API=OFF`. - Building with t8code support is optional. It requires to pass `-DT8CODE_ROOT=`. @@ -306,7 +308,7 @@ To try this out, perform the following steps: *using cmake* - Add ``` - -DUSE_PACKAGE_COMPILER=ON -DJULIA_PROJECT_PATH= + -DLIBTRIXI_USE_PACKAGE_COMPILER=ON -DJULIA_PROJECT_PATH= ``` to your cmake call (see above) 3. From inside the `examples` folder you should be able to run the example (in parallel) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 508fb4bf..be992e3c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -17,6 +17,11 @@ if ( NOT T8CODE_FOUND ) list( FILTER EXAMPLES EXCLUDE REGEX "trixi_controller_baroclinic.*" ) endif() +if (NOT LIBTRIXI_BUILD_FORTRAN_API) + # Remove Fortran files if the the Fortran API is not build + list( FILTER EXAMPLES EXCLUDE REGEX ".*\.f90" ) +endif() + foreach ( EXAMPLE ${EXAMPLES} ) get_filename_component ( EXAMPLE_EXT ${EXAMPLE} EXT ) @@ -41,7 +46,7 @@ foreach ( EXAMPLE ${EXAMPLES} ) ${TARGET_NAME} PRIVATE MPI::MPI_${EXAMPLE_LANG} ${PROJECT_NAME} ) - if ( NOT USE_PACKAGE_COMPILER ) + if ( NOT LIBTRIXI_USE_PACKAGE_COMPILER ) target_link_libraries( ${TARGET_NAME} PRIVATE ${PROJECT_NAME}_tls ) endif() if ( T8CODE_FOUND ) @@ -53,7 +58,9 @@ foreach ( EXAMPLE ${EXAMPLES} ) ${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src ) - if ( T8CODE_FOUND ) + + if ( LIBTRIXI_BUILD_FORTRAN_API AND T8CODE_FOUND ) + # Add the t8code include directory of the Fortran module file target_include_directories( ${TARGET_NAME} PRIVATE ${T8CODE_ROOT}/include/t8_fortran_interface/ ) endif()