Skip to content
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

Addition of cmake #83

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 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
18 changes: 17 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
fail-fast: false
matrix:
build: [fpm, meson]
build: [cmake, fpm, meson]
os: [ubuntu-latest, macos-latest, windows-latest]
gcc: [10] # Version of GFortran we want to use.
build-type: [debug]
Expand All @@ -25,6 +25,7 @@ jobs:
CC: gcc
FPM_FC: gfortran
FPM_CC: gcc
BUILD_DIR: ${{ matrix.build == 'cmake' && 'build' || '.' }}
steps:
- name: Checkout code
uses: actions/checkout@v2
Expand Down Expand Up @@ -71,6 +72,21 @@ jobs:
extra-specs: |
${{ matrix.build-type == 'coverage' && 'gcovr' || '' }}

- name: Configure (cmake)
if: ${{ matrix.build == 'cmake' }}
run: >-
cmake -Wdev
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
-S . -B ${{ env.BUILD_DIR }}

- name: Compile (cmake)
if: ${{ matrix.build == 'cmake' }}
cmake --build ${{ env.BUILD_DIR }} --parallel
jvdp1 marked this conversation as resolved.
Show resolved Hide resolved

- name: Run test (cmake)
if: ${{ matrix.build == 'cmake' }}
run: cmake --build ${{ env.BUILD_DIR }} --target test

- name: Compile (fpm)
if: ${{ matrix.build == 'fpm' }}
run: fpm build --profile release
Expand Down
35 changes: 35 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 3.14.0)

# Include overwrites before setting up the project
set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_SOURCE_DIR}/config/DefaultFlags.cmake)

project(minpack
LANGUAGES Fortran
VERSION "2.0.0"
DESCRIPTION "Minpack includes software for solving nonlinear equations and nonlinear least squares problems"
)

include(CTest)

# Follow GNU conventions for installation directories
include(GNUInstallDirs)

# --- CMake specific configuration and package data export
add_subdirectory(config)

# --- compiler feature checks
include(CheckFortranSourceCompiles)
include(CheckFortranSourceRuns)

add_subdirectory(src)

if(BUILD_TESTING)
enable_testing()
add_subdirectory(test)
add_subdirectory(examples)
endif()

install(EXPORT ${PROJECT_NAME}-targets
NAMESPACE ${PROJECT_NAME}::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Further updates are planned...
To build this project from the source code in this repository you need to have
a Fortran compiler supporting Fortran 2008 and one of the supported build systems:

- [cmake](https://cmake.org) version 3.14.0 or newer
- [fpm](https://fpm.fortran-lang.org) version 0.3.0 or newer
- [meson](https://mesonbuild.com) version 0.55 or newer, with
a build-system backend, *i.e.* [ninja](https://ninja-build.org) version 1.7 or newer
Expand All @@ -44,6 +45,21 @@ cd minpack
```


#### Building with cmake

Invoke cmake in the project root with

```
cmake -B build
cmake --build build
```

To run the testsuite use

```
cmake --build build --target test
```

#### Building with fpm

Invoke fpm in the project root with
Expand Down
53 changes: 53 additions & 0 deletions config/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# SPDX-Identifier: MIT

if(NOT DEFINED CMAKE_INSTALL_MODULEDIR)
set(
CMAKE_INSTALL_MODULEDIR
"${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}"
CACHE
STRING
"Directory in prefix to install generated module files"
)
endif()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)

# Export a pkg-config file
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/template.pc"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
@ONLY
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

# Export CMake package file
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/template.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
if(BUILD_SHARED_LIBS OR PROJECT_VERSION_MAJOR EQUAL 0)
# Due to the uncertain ABI compatibility of Fortran shared libraries
# limit compatibility for dynamic linking to same minor version.
set(COMPATIBILITY SameMinorVersion)
else()
# Require API compatibility via semantic versioning for static linking.
set(COMPATIBILITY SameMajorVersion)
endif()
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
VERSION "${PROJECT_VERSION}"
COMPATIBILITY ${COMPATIBILITY}
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
50 changes: 50 additions & 0 deletions config/DefaultFlags.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
set(
CMAKE_Fortran_FLAGS_INIT
"-fimplicit-none"
"-ffree-line-length-132"
)
set(
CMAKE_Fortran_FLAGS_RELEASE_INIT
)
set(
CMAKE_Fortran_FLAGS_DEBUG_INIT
"-Wall"
"-Wextra"
"-Wimplicit-procedure"
"-std=f2018"
)
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel")
set(
CMAKE_Fortran_FLAGS_INIT
)
set(
CMAKE_Fortran_FLAGS_RELEASE_INIT
)
if(WIN32)
set(
CMAKE_Fortran_FLAGS_DEBUG_INIT
"/stand:f18"
"/warn:declarations,general,usage,interfaces,unused"
)
else()
set(
CMAKE_Fortran_FLAGS_DEBUG_INIT
"-stand f18"
"-warn declarations,general,usage,interfaces,unused"
)
endif()
else()
set(
CMAKE_Fortran_FLAGS_INIT
)
set(
CMAKE_Fortran_FLAGS_RELEASE_INIT
)
set(
CMAKE_Fortran_FLAGS_DEBUG_INIT
)
endif()
string(REPLACE ";" " " CMAKE_Fortran_FLAGS_INIT "${CMAKE_Fortran_FLAGS_INIT}")
string(REPLACE ";" " " CMAKE_Fortran_FLAGS_RELEASE_INIT "${CMAKE_Fortran_FLAGS_RELEASE_INIT}")
string(REPLACE ";" " " CMAKE_Fortran_FLAGS_DEBUG_INIT "${CMAKE_Fortran_FLAGS_DEBUG_INIT}")
5 changes: 5 additions & 0 deletions config/template.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@")
include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
endif()
10 changes: 10 additions & 0 deletions config/template.pc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix=@CMAKE_INSTALL_PREFIX@
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
moduledir=${prefix}/@CMAKE_INSTALL_MODULEDIR@

Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
Libs: -L${libdir} -l@PROJECT_NAME@
Cflags: -I${includedir} -I${moduledir}
19 changes: 19 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
macro(ADDEXAMPLE name)
add_executable(example_${name} example_${name}.f90)
target_link_libraries(example_${name} "${PROJECT_NAME}")
add_test(NAME ${name}
COMMAND $<TARGET_FILE:example_${name}> ${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endmacro(ADDEXAMPLE)

set(examples
"hybrd"
"hybrd1"
"lmder1"
"lmdif1"
"primes"
)

foreach(example IN LISTS examples)
ADDEXAMPLE(${example})
endforeach()
44 changes: 44 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
set(SRC
minpack.f90
minpack_capi.f90
)

add_library(${PROJECT_NAME} ${SRC})

set_target_properties(
${PROJECT_NAME}
PROPERTIES
POSITION_INDEPENDENT_CODE ON
WINDOWS_EXPORT_ALL_SYMBOLS ON
)

if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU AND CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 10.0)
target_compile_options(
${PROJECT_NAME}
PRIVATE
$<$<COMPILE_LANGUAGE:Fortran>:-fno-range-check>
)
endif()

set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/)
# We need the module directory before we finish the configure stage since the
# build interface might resolve before the module directory is generated by CMake
if(NOT EXISTS "${LIB_MOD_DIR}")
make_directory("${LIB_MOD_DIR}")
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES
Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR})

target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${LIB_MOD_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_MODULEDIR}>
)

install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${CMAKE_INSTALL_MODULEDIR}")
22 changes: 22 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
macro(ADDTEST name)
add_executable(test_${name} test_${name}.f90)
target_link_libraries(test_${name} "${PROJECT_NAME}")
add_test(NAME ${name}
COMMAND $<TARGET_FILE:test_${name}> ${CMAKE_CURRENT_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endmacro(ADDTEST)

set(tests
"chkder"
"hybrd"
"hybrj"
"lmder"
"lmdif"
"lmstr"
)

foreach(test IN LISTS tests)
ADDTEST(${test})
endforeach()