Skip to content

Addidtion of Findneural-fortran.cmake #178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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