Skip to content

Commit

Permalink
Addidtion of Findneural-fortran.cmake (#178)
Browse files Browse the repository at this point in the history
* Addition of Findneural-fortran.cmake

* Rename libneural to libneural-fortran

* Adapt test/CmakeLists.txt

* adapt example/CMakeLists.txt
  • Loading branch information
jvdp1 authored Apr 19, 2024
1 parent f7b6006 commit c3924b5
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 6 deletions.
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ include(cmake/functional.cmake)
include(cmake/h5fortran.cmake)
include(cmake/json.cmake)

# library to archive (libneural.a)
add_library(neural
# library to archive (libneural-fortran.a)
add_library(neural-fortran
src/nf.f90
src/nf/nf_activation.f90
src/nf/nf_base_layer.f90
Expand Down Expand Up @@ -64,14 +64,14 @@ add_library(neural
src/nf/io/nf_io_hdf5_submodule.f90
)

target_link_libraries(neural PRIVATE
target_link_libraries(neural-fortran PRIVATE
functional::functional
h5fortran::h5fortran
HDF5::HDF5
jsonfortran::jsonfortran
)

install(TARGETS neural)
install(TARGETS neural-fortran)

# Remove leading or trailing whitespace
string(REGEX REPLACE "^ | $" "" LIBS "${LIBS}")
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,23 @@ ctest

to run the tests.

## Using neural-fortran in your project

You can use the CMake module available [here](cmake/Findneural-fortran.cmake) to
find or fetch an installation of this project while configuring your project. This
module makes sure that the `neural-fortran::neural-fortran` target is always generated regardless
of how the neural-fortran is included in the project.

You can configure neural-fortran by setting the appropriate options before
including the subproject.

The following should be added in the CMake file of your directory:
```cmake
if(NOT TARGET "neural-fortran::neural-fortran")
find_package("neural-fortran" REQUIRED)
endif()
```

## Examples

The easiest way to get a sense of how to use neural-fortran is to look at
Expand Down
179 changes: 179 additions & 0 deletions cmake/Findneural-fortran.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# SPDX-Identifier: MIT
# Based on https://github.com/fortran-lang/stdlib-cmake-example

#[[.rst:
Find neural-fortran
-------------------
Makes the neural-fortran library project available.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported target, if found:
``neural-fortran::neural-fortran``
The neural-fortran library
Result Variables
^^^^^^^^^^^^^^^^
This module will define the following variables:
``NEURAL-FORTRAN_FOUND``
True if the neural-fortran library is available
``NEURAL-FORTRAN_SOURCE_DIR``
Path to the source directory of the neural-fortran library project,
only set if the project is included as source.
``NEURAL-FORTRAN_BINARY_DIR``
Path to the binary directory of the neural-fortran library project,
only set if the project is included as source.
Cache variables
^^^^^^^^^^^^^^^
The following cache variables may be set to influence the library detection:
``NEURAL-FORTRAN_FIND_METHOD``
Methods to find or make the project available. Available methods are
- ``cmake``: Try to find via CMake config file
- ``pkgconf``: Try to find via pkg-config file
- ``subproject``: Use source in subprojects directory
- ``fetch``: Fetch the source from upstream
``NEURAL-FORTRAN_DIR``
Used for searching the CMake config file
``NEURAL-FORTRAN_SUBPROJECT``
Directory to find the neural-fortran library subproject, relative to the project root
#]]

set(_lib "neural-fortran")
set(_pkg "NEURAL-FORTRAN")
set(_url "https://github.com/modern-fortran/neural-fortran.git")

if(NOT DEFINED "${_pkg}_FIND_METHOD")
if(DEFINED "${PROJECT_NAME}-dependency-method")
set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}")
else()
set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch")
endif()
set("_${_pkg}_FIND_METHOD")
endif()

foreach(method ${${_pkg}_FIND_METHOD})
if(TARGET "${_lib}::${_lib}")
break()
endif()

if("${method}" STREQUAL "cmake")
message(STATUS "${_lib}: Find installed package")
if(DEFINED "${_pkg}_DIR")
set("_${_pkg}_DIR")
set("${_lib}_DIR" "${_pkg}_DIR")
endif()
find_package("${_lib}" CONFIG)
if("${_lib}_FOUND")
message(STATUS "${_lib}: Found installed package")
break()
endif()
endif()

if("${method}" STREQUAL "pkgconf")
find_package(PkgConfig QUIET)
pkg_check_modules("${_pkg}" QUIET "${_lib}")
if("${_pkg}_FOUND")
message(STATUS "Found ${_lib} via pkg-config")

add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
target_link_libraries(
"${_lib}::${_lib}"
INTERFACE
"${${_pkg}_LINK_LIBRARIES}"
)
target_include_directories(
"${_lib}::${_lib}"
INTERFACE
"${${_pkg}_INCLUDE_DIRS}"
)

break()
endif()
endif()

if("${method}" STREQUAL "subproject")
if(NOT DEFINED "${_pkg}_SUBPROJECT")
set("_${_pkg}_SUBPROJECT")
set("${_pkg}_SUBPROJECT" "subprojects/${_lib}")
endif()
set("${_pkg}_SOURCE_DIR" "${PROJECT_SOURCE_DIR}/${${_pkg}_SUBPROJECT}")
set("${_pkg}_BINARY_DIR" "${PROJECT_BINARY_DIR}/${${_pkg}_SUBPROJECT}")
if(EXISTS "${${_pkg}_SOURCE_DIR}/CMakeLists.txt")
message(STATUS "Include ${_lib} from ${${_pkg}_SUBPROJECT}")
add_subdirectory(
"${${_pkg}_SOURCE_DIR}"
"${${_pkg}_BINARY_DIR}"
)

add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
target_link_libraries("${_lib}::${_lib}" INTERFACE "${_lib}")

# We need the module directory in the subproject before we finish the configure stage
if(NOT EXISTS "${${_pkg}_BINARY_DIR}/mod_files")
make_directory("${${_pkg}_BINARY_DIR}/mod_files")
endif()

break()
endif()
endif()

if("${method}" STREQUAL "fetch")
message(STATUS "Retrieving ${_lib} from ${_url}")
include(FetchContent)
FetchContent_Declare(
"${_lib}"
GIT_REPOSITORY "${_url}"
GIT_TAG "HEAD"
)
FetchContent_MakeAvailable("${_lib}")

add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
target_link_libraries("${_lib}::${_lib}" INTERFACE "${_lib}")

# We need the module directory in the subproject before we finish the configure stage
FetchContent_GetProperties("${_lib}" SOURCE_DIR "${_pkg}_SOURCE_DIR")
FetchContent_GetProperties("${_lib}" BINARY_DIR "${_pkg}_BINARY_DIR")
if(NOT EXISTS "${${_pkg}_BINARY_DIR}/mod_files")
make_directory("${${_pkg}_BINARY_DIR}/mod_files")
endif()

break()
endif()

endforeach()

if(TARGET "${_lib}::${_lib}")
set("${_pkg}_FOUND" TRUE)
else()
set("${_pkg}_FOUND" FALSE)
endif()

if(DEFINED "_${_pkg}_SUBPROJECT")
unset("${_pkg}_SUBPROJECT")
unset("_${_pkg}_SUBPROJECT")
endif()
if(DEFINED "_${_pkg}_DIR")
unset("${_lib}_DIR")
unset("_${_pkg}_DIR")
endif()
if(DEFINED "_${_pkg}_FIND_METHOD")
unset("${_pkg}_FIND_METHOD")
unset("_${_pkg}_FIND_METHOD")
endif()
unset(_lib)
unset(_pkg)
unset(_url)
2 changes: 1 addition & 1 deletion example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ foreach(execid
)
add_executable(${execid} ${execid}.f90)
target_link_libraries(${execid} PRIVATE
neural
neural-fortran
h5fortran::h5fortran
jsonfortran::jsonfortran
${LIBS}
Expand Down
2 changes: 1 addition & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ foreach(execid
loss
)
add_executable(test_${execid} test_${execid}.f90)
target_link_libraries(test_${execid} PRIVATE neural h5fortran::h5fortran jsonfortran::jsonfortran ${LIBS})
target_link_libraries(test_${execid} PRIVATE neural-fortran h5fortran::h5fortran jsonfortran::jsonfortran ${LIBS})

add_test(NAME test_${execid} COMMAND test_${execid})
endforeach()
Expand Down

0 comments on commit c3924b5

Please sign in to comment.