Skip to content

Commit

Permalink
Merge pull request #29 from zerothi/cmake
Browse files Browse the repository at this point in the history
Cmake addition
  • Loading branch information
zerothi authored Feb 27, 2023
2 parents 14f9104 + 52ebd7c commit 6a96471
Show file tree
Hide file tree
Showing 15 changed files with 512 additions and 10 deletions.
73 changes: 73 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)

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

# Define fdict project and languages used
project(fdict
LANGUAGES Fortran
DESCRIPTION "Fortran dictionary for arbitrary data-types"
)


# Define project versions
file(STRINGS "${PROJECT_SOURCE_DIR}/VERSION" PROJECT_VERSION)

# Listify the string
string(REPLACE "." ";" VERSION_LIST ${PROJECT_VERSION})
list(GET VERSION_LIST 0 PROJECT_VERSION_MAJOR)
list(GET VERSION_LIST 1 PROJECT_VERSION_MINOR)
list(GET VERSION_LIST 2 PROJECT_VERSION_PATCH)
unset(VERSION_LIST)


# Define library specific content
set(PROJECT_AUTHOR "Nick Papior")
set(PROJECT_DESCRIPTION "Fortran dictionary for arbitrary data-types")
set(PROJECT_URL "https://github.com/zerothi/fdict")
set(PROJECT_LICENSE "Mozilla Public License, 2.0 (MPL-2.0)")
message("** PROJECT_NAME = ${PROJECT_NAME}")
message("** Please report any build problems here: ${PROJECT_URL}")


# Define the module temporary location
#set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/modules/)

list(APPEND FYPPFLAGS
"-DPROJECT_NAME=\\\"${PROJECT_NAME}\\\""
"-DPROJECT_VERSION=\\\"${PROJECT_VERSION}\\\""
"-DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}"
"-DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR}"
"-DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}"
)


# Add our custom definitions
add_subdirectory(config)

# Define the allocatable array sizes
set(F_ARRAY ":")
foreach(IR RANGE 2 ${CMAKE_MAXIMUM_RANK})
list(APPEND F_ARRAY ":")
endforeach()
string(REPLACE ";" "," F_ARRAY "${F_ARRAY}")

# Once we have the sizes of the settings defined, we will add a check that the compiler will actually handle this.
check_fortran_source_compiles("real, allocatable :: array(${F_ARRAY}); end" fmaximum_rank SRC_EXT f90)
unset(F_ARRAY)
check_fortran_source_runs("use, intrinsic :: iso_fortran_env, only : real128; real(real128) :: x; x = x+1; end" f03real128)

foreach(V IN ITEMS fmaximum_rank f03real128)
if(NOT ${${V}})
message(FATAL_ERROR "Could not succesfully test compiler capability: ${V}")
endif()
endforeach()


add_subdirectory(src)


install(EXPORT ${PROJECT_NAME}-targets
NAMESPACE ${PROJECT_NAME}::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
14 changes: 7 additions & 7 deletions Makefile.project
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ _SMEKA_project = 1
# Contains specific default information for this project

# Step this version upon new versions
PROJECT_MAJOR = 0
PROJECT_MINOR = 9
PROJECT_PATCH = 0
PROJECT_VERSION = $(PROJECT_MAJOR).$(PROJECT_MINOR).$(PROJECT_PATCH)
PROJECT_VERSION_MAJOR = 0
PROJECT_VERSION_MINOR = 9
PROJECT_VERSION_PATCH = 0
PROJECT_VERSION = $(PROJECT_VERSION_MAJOR).$(PROJECT_VERSION_MINOR).$(PROJECT_VERSION_PATCH)

# These are constant default
PROJECT_NAME = fdict
Expand All @@ -16,9 +16,9 @@ FDICT_LIB ?= fdict$(LIB_SUFFIX)
FDICT_LIB_STATIC ?= lib$(FDICT_LIB).a
FDICT_LIB_SHARED ?= lib$(FDICT_LIB).so

FYPPFLAGS += -DPROJECT_MAJOR=$(PROJECT_MAJOR)
FYPPFLAGS += -DPROJECT_MINOR=$(PROJECT_MINOR)
FYPPFLAGS += -DPROJECT_PATCH=$(PROJECT_PATCH)
FYPPFLAGS += -DPROJECT_VERSION_MAJOR=$(PROJECT_VERSION_MAJOR)
FYPPFLAGS += -DPROJECT_VERSION_MINOR=$(PROJECT_VERSION_MINOR)
FYPPFLAGS += -DPROJECT_VERSION_PATCH=$(PROJECT_VERSION_PATCH)

# Define custom options for fdict
STATIC ?= 1
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ To enable the non-default data types you can do so with (Makefile scheme):
FYPPFLAGS += -DWITH_LOG64=1 # for logical kind(18)
FYPPFLAGS += -DWITH_ISO_C=1 # for enabling c_ptr and c_funptr

For `cmake` the same arguments can be made.

By default `fdict` generates the kind specifications from the `selected_*_kind` routines,
however, if one wishes to use the `iso_fortran_env` module simply add `FYPPFLAGS += -DWITH_ISO_ENV`.

Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.9.0
152 changes: 152 additions & 0 deletions config/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Ensure we use some basic packages

# Project installation follows GNU installation directory convention
include(GNUInstallDirs)

include(ProjectOptions.cmake)

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

set(CMAKE_INSTALL_CMAKECONFIG_DIR
"${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)


# Export a pkg-config file
configure_file(
"${PROJECT_SOURCE_DIR}/fdict.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
@ONLY
)

# Install pkg-config files
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)

# Export CMake package file
include(CMakePackageConfigHelpers)

# Export a cmake package configure file
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/template.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_CMAKECONFIG_DIR}"
)

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()

# Export a package version file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
VERSION "${PROJECT_VERSION}"
COMPATIBILITY ${COMPATIBILITY}
)

# Install cmake configuration files
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_CMAKECONFIG_DIR}"
)


# Preprocesses a list of files with given preprocessor and preprocessor options
#
# Args:
# preproc [in]: Preprocessor program
# preprocopts [in]: Preprocessor options
# srcext [in]: File extension of the source files
# trgext [in]: File extension of the target files
# srcfiles [in]: List of the source files
# trgfiles [out]: Contains the list of the preprocessed files on exit
#
function(preprocess preproc preprocopts srcext trgext srcfiles trgfiles)

set(_trgfiles)
foreach(srcfile IN LISTS srcfiles)
string(REGEX REPLACE "\\.${srcext}$" ".${trgext}" trgfile ${srcfile})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${trgfile}
COMMAND ${preproc} ${preprocopts} ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile} ${CMAKE_CURRENT_BINARY_DIR}/${trgfile}
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/${srcfile})
list(APPEND _trgfiles ${CMAKE_CURRENT_BINARY_DIR}/${trgfile})
endforeach()
set(${trgfiles} ${_trgfiles} PARENT_SCOPE)

endfunction()

# Define a function for fyppifying sources
function(fyppify)
# Parse arguments
set(options "")
set(oneValueArgs FYPP EXTIN EXTOUT COMMENT OUTPUT)
set(multiValueArgs FLAGS FILES)
cmake_parse_arguments(
_fyppify "${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)

# Now handle arguments
#[==[
message(INFO "Before parsing inputs:
comment=${_fyppify_COMMENT}
fypp=${_fyppify_FYPP}
EXTIN=${_fyppify_EXTIN}
EXTOUT=${_fyppify_EXTOUT}
FLAGS=${_fyppify_FLAGS}
FILES=${_fyppify_FILES}
")
]==]

if(NOT DEFINED _fyppify_FYPP)
set(_fyppify_FYPP ${FYPP})
endif()
if(NOT DEFINED _fyppify_EXTIN)
set(_fyppify_EXTIN "fypp")
endif()
if(NOT DEFINED _fyppify_EXTOUT)
set(_fyppify_EXTOUT "f90")
endif()
if(DEFINED _fyppify_COMMENT)
message(VERBOSE "-- Setting up fyppify: ${_fyppify_COMMENT}")
endif()
if(NOT DEFINED _fyppify_FLAGS)
set(_fyppify_FLAGS "")
endif()
if(NOT DEFINED _fyppify_FILES)
message(FATAL_ERROR "fyppify requires FILES arguments to determine which files to preprocess")
endif()

#[==[
message(INFO "After parsing inputs:
comment=${_fyppify_COMMENT}
fypp=${_fyppify_FYPP}
EXTIN=${_fyppify_EXTIN}
EXTOUT=${_fyppify_EXTOUT}
FLAGS=${_fyppify_FLAGS}
FILES=${_fyppify_FILES}
")
]==]

# Lets do the preprocessing
preprocess("${_fyppify_FYPP}" "${_fyppify_FLAGS}"
"${_fyppify_EXTIN}" "${_fyppify_EXTOUT}"
"${_fyppify_FILES}" _outfiles)
if(DEFINED _fyppify_OUTPUT)
set(${_fyppify_OUTPUT} ${_outfiles} PARENT_SCOPE)
endif()

endfunction()
42 changes: 42 additions & 0 deletions config/DefaultFlags.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
# GNU compiler gfortran
set(
CMAKE_Fortran_FLAGS_INIT
"-fimplicit-none"
)
set(
CMAKE_Fortran_FLAGS_RELEASE_INIT
)
set(
CMAKE_Fortran_FLAGS_DEBUG_INIT
"-Wall"
"-Wextra"
"-Wimplicit-procedure"
)
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel")
# Intel compiler ifort
set(
CMAKE_Fortran_FLAGS_INIT
)
set(
CMAKE_Fortran_FLAGS_RELEASE_INIT
)
set(
CMAKE_Fortran_FLAGS_DEBUG_INIT
"-warn declarations,general,usage,interfaces,unused"
)
else()
# unknown compiler (possibly)
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}")
62 changes: 62 additions & 0 deletions config/ProjectOptions.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Here we define all options that are related to fdict

# Ensure we have the program fypp installed
find_program(FYPP fypp)
if(NOT FYPP)
message(FATAL_ERROR "Could not find executable fypp -- it is required for the pre-processing step")
endif()

# We need to define certain variables before the initial configuration of this project
if(NOT DEFINED CMAKE_MAXIMUM_RANK)
set(CMAKE_MAXIMUM_RANK 5 CACHE STRING "Maximum array rank for generated procedures")
endif()

# Whether we should use the iso_fortran_env for data-types
message(CHECK_START "Requested use of intrinsic fortran module (iso_fortran_env) for data-types")
if(DEFINED "WITH_ISO_ENV}")
message(CHECK_PASS "used")
list(APPEND FYPPFLAGS "-DWITH_ISO_ENV=$<BOOL:${WITH_ISO_ENV}>")
else()
message(CHECK_FAIL "not used")
endif()


# Parse data-type options
message(CHECK_START "Checking for data-type interfaces")
list(APPEND CMAKE_MESSAGE_INDENT " ")
foreach(var INT8 INT16 REAL80 REAL128 LOG8 LOG16 LOG64 ISO_C)
message(CHECK_START "data-type ${var}")
if(DEFINED "WITH_${var}")
message(CHECK_PASS "added")
list(APPEND FYPPFLAGS "-DWITH_${var}=$<BOOL:${WITH_${var}}>")
else()
message(CHECK_FAIL "not added")
endif()
endforeach()
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "done")

# Global maxrank
message(CHECK_START "Checking for data-type rank size interfaces")
list(APPEND CMAKE_MESSAGE_INDENT " ")
message(CHECK_START "default rank size")
if(DEFINED "MAXRANK")
message(CHECK_PASS "found size = ${MAXRANK}")
list(APPEND FYPPFLAGS "-DMAXRANK=${MAXRANK}")
else()
set(MAXRANK 5)
message(CHECK_FAIL "using default size = ${MAXRANK}")
endif()

# Parse rank sizes
foreach(var INT REAL CMPLX LOG ISO_C)
message(CHECK_START "rank size of ${var}")
if(DEFINED "MAXRANK_${var}")
message(CHECK_PASS "found size = ${MAXRANK_${var}}")
list(APPEND FYPPFLAGS "-DMAXRANK_${var}=${MAXRANK_${var}}")
else()
message(CHECK_FAIL "using default size = ${MAXRANK}")
endif()
endforeach()
list(POP_BACK CMAKE_MESSAGE_INDENT)
message(CHECK_PASS "done")
5 changes: 5 additions & 0 deletions config/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
These configuration files are highly inspired from the
github.com/fortran-lang/stdlib project.

I acknowledge and thank them for their continued support to
the Fortran community!
Loading

0 comments on commit 6a96471

Please sign in to comment.