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

Cmake and guix #69

Merged
merged 18 commits into from
Nov 18, 2021
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
46 changes: 46 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
cmake_minimum_required(VERSION 3.16)

# =========== SETUP THE PROJECT =============

# Initialize the CMake project.
project(Trexio
VERSION 2.0.0
DESCRIPTION "TREX I/O library"
LANGUAGES C Fortran
)

# Request the C99 standard.
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)

# Optional configure for developer mode to generate source code from org-mode files.
option(TREXIO_DEVEL "TREXIO developer mode (for code generation)." OFF)

if(EXISTS ".git/config")
set(TREXIO_DEVEL ON)
find_package(Python3 REQUIRED)
if(Python3_FOUND)
if(Python3_VERSION_MINOR LESS 6)
message(FATAL_ERROR "Required Python3 version :: >= 3.6; Found :: ${Python3_VERSION}")
else()
message(STATUS "Python3 version :: ${Python3_VERSION}")
endif()
endif()
find_program(EMACS NAMES emacs REQUIRED)
if(NOT EMACS-NOTFOUND)
message(STATUS "EMACS detected :: ${EMACS}")
else()
message(FATAL_ERROR "EMACS not found. It is required to produce TREXIO source code from org-mode files.")
endif()
endif()

# Set directories to be included at build time.
include_directories(include)

# Add subdirectory with add_library(trexio) specifications.
add_subdirectory(src)

# Add subdirectory with unit tests.
enable_testing()
add_subdirectory(tests)

11 changes: 9 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ ORG_FILES = \

src_libtrexio_la_SOURCES = $(SOURCES)

# Include CMake-related files in the distribution.
dist_data_DATA = CMakeLists.txt \
src/CMakeLists.txt \
tests/CMakeLists.txt \
cmake/cmake_uninstall.cmake.in \
cmake/FindTREXIO.cmake

# =============== TESTS =============== #

TESTS_C = \
Expand Down Expand Up @@ -174,8 +181,8 @@ dist_html_DATA = $(HTML_FILES)

$(HTML_TANGLED): $(htmlizer)

html: $(dist_html_DATA)
doc: html
html-local: $(dist_html_DATA)
doc: html-local

# =============== DEVELOPER MODE =============== #

Expand Down
77 changes: 77 additions & 0 deletions cmake/FindTREXIO.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#===========================================

# Try to find TREXIO library;
# If found, it will define the following variables (note the plural form):
# TREXIO_FOUND - System has libtrexio;
# TREXIO_INCLUDE_DIRS - The TREXIO include directories;
# TREXIO_LIBRARIES - The libraries needed to use TREXIO;

# If TREXIO has been installed in a non-standard location, one can set an
# environment variable $TREXIO_DIR in the current shell:
# $ export TREXIO_DIR=<custom_path>
# to indicate the prefix used during the TREXIO installation
# (typically `./configure prefix=<custom_path> ..` or `cmake -DCMAKE_INSTALL_DIR=<custom_path> ..`)

# This file should be located WITHIN your project source tree.
# (e.g. in cmake/FindTREXIO.cmake)
# How to use it in your project CMakeLists.txt:

# This is needed to locate FindTREXIO.cmake file, modify it according to your source tree.
# list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")

# find_package(TREXIO)
# if (TREXIO_FOUND)
# include_directories(${TREXIO_INCLUDE_DIRS})
# target_link_libraries(your_target ${TREXIO_LIBRARIES})
# endif()

#===========================================

# This file is distirbuted under the BSD 3-Clause License.
# Copyright (c) 2021, TREX Center of Excellence

#===========================================

message("<FindTREXIO.cmake>")

set(TREXIO_SEARCH_PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)

find_path(TREXIO_INCLUDE_DIR
NAMES trexio.h
HINTS $ENV{TREXIO_DIR}
PATH_SUFFIXES include/trexio include
PATHS ${TREXIO_SEARCH_PATHS}
)


# No need to specify platform-specific prefix (e.g. libtrexio on Unix) or
# suffix (e.g. .so on Unix or .dylib on MacOS) in NAMES. CMake takes care of that.
find_library(TREXIO_LIBRARY
NAMES trexio
HINTS $ENV{TREXIO_DIR}
PATH_SUFFIXES lib64 lib
PATHS ${TREXIO_SEARCH_PATHS}
)

message("<FindTREXIO.cmake>")

# Handle the QUIETLY and REQUIRED arguments and set TREXIO_FOUND to TRUE if
# all listed variables are TRUE.
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(TREXIO DEFAULT_MSG TREXIO_LIBRARY TREXIO_INCLUDE_DIR )
MARK_AS_ADVANCED(TREXIO_INCLUDE_DIR TREXIO_LIBRARY)

# Mot setting _INCLUDE_DIR and _LIBRARIES is considered a bug,
# see https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/How-To-Find-Libraries
set(TREXIO_LIBRARIES ${TREXIO_LIBRARY})
set(TREXIO_INCLUDE_DIRS ${TREXIO_INCLUDE_DIR})

24 changes: 24 additions & 0 deletions cmake/cmake_uninstall.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Needed to make uninstall target in CMake, see the CMake FAQ:
# https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake

if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()

file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()
18 changes: 10 additions & 8 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,18 @@

AC_PREREQ([2.69])
AC_INIT([trexio],[2.0.0],[https://github.com/TREX-CoE/trexio/issues])

AC_CONFIG_SRCDIR([Makefile.in])
AC_CONFIG_HEADERS([include/config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-config])

AM_INIT_AUTOMAKE([subdir-objects color-tests parallel-tests silent-rules 1.11])
AM_MAINTAINER_MODE()
AM_PROG_AR

LT_PREREQ([2.2])
LT_INIT

# Activate developer mode when the source is the git repository.
# Otherwise, it is the source distribution and the developer mode should not be activated.
Expand All @@ -13,13 +23,6 @@ AC_CHECK_FILE([$TEST_IFEXISTS],
[enable_maintainer_mode="yes"],
)

AM_MAINTAINER_MODE()
LT_PREREQ([2.2])
LT_INIT
AC_CONFIG_SRCDIR([Makefile.in])
AC_CONFIG_HEADERS([include/config.h])
AC_CONFIG_MACRO_DIR([m4])

VERSION_MAJOR=`echo ${PACKAGE_VERSION} | cut -d. -f1`
VERSION_MINOR=`echo ${PACKAGE_VERSION} | cut -d. -f2`
VERSION_PATCH=`echo ${PACKAGE_VERSION} | cut -d. -f3 | cut -d- -f1`
Expand Down Expand Up @@ -60,7 +63,6 @@ PKG_CFLAGS=""
PKG_LIBS=""

AC_PROG_INSTALL
AM_PROG_AR
AC_PROG_LN_S
AC_PROG_GREP

Expand Down
147 changes: 147 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@

# ========= DEFINE TREXIO C LIBRARY =========

# Set a list of TREXIO source and header files that are always compiled.
set(TREXIO_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/trexio.c
${CMAKE_CURRENT_SOURCE_DIR}/trexio_text.c
)
set(TREXIO_PUBLIC_HEADERS ${CMAKE_SOURCE_DIR}/include/trexio.h)
set(TREXIO_PRIVATE_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/trexio_s.h
${CMAKE_CURRENT_SOURCE_DIR}/trexio_private.h
${CMAKE_CURRENT_SOURCE_DIR}/trexio_text.h
)

# By default, the shared TREXIO library is built (even without -DBUILD_SHARED_LIBS=ON).
# To change this behaviour, append -DBUILD_STATIC_LIBS=ON to the cmake call.
option(BUILD_SHARED_LIBS "Build the shared library" ON)
option(BUILD_STATIC_LIBS "Build the static library" OFF)

if(BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)
set(BUILD_SHARED_LIBS OFF)
endif()

# Conditional SHARED/STATIC build for TREXIO library.
if(BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)

message(STATUS "TREXIO :: shared C library will be built")
add_library(trexio SHARED)

elseif(NOT BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)

message(STATUS "TREXIO :: static C library will be built")
add_library(trexio STATIC)
# Static TREXIO has to be compiled with -fPIC flag. For Shared it is done by default.
set_property(TARGET trexio PROPERTY POSITION_INDEPENDENT_CODE ON)

else()
message(FATAL_ERROR "Building both static and shared TREXIO simultaneously is not supported.")
endif()

# Set TREXIO version and include files.
set_target_properties(trexio PROPERTIES
VERSION ${PROJECT_VERSION}
PUBLIC_HEADER ${TREXIO_PUBLIC_HEADERS}
)

# ============= CONFIGURE HDF5 ==============

# By defaulti, TREXIO is configured with the HDF5 support.
# To change this, append -DENABLE_HDF5=OFF to the cmake call.
option(ENABLE_HDF5 "Enable HDF5 support" ON)

if(ENABLE_HDF5)
# Try to detect HDF5 installation using built-in FindHDF5.cmake macro.
find_package(HDF5 REQUIRED COMPONENTS C HL)

if(HDF5_FOUND)
message(STATUS "HDF5 version :: ${HDF5_VERSION}")
message(STATUS "HDF5 include dir :: ${HDF5_INCLUDE_DIRS}")
else()
# Download and install HDF5 library using FetchContent
# ...
# For now - raise a FATAL_ERROR
message(FATAL_ERROR "HDF5 is enabled but not found.")
endif()

# If HDF5 found:
# - append the trexio_hdf5.c source file with the HDF5 back end to the list TREXIO_SOURCES
list(APPEND TREXIO_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/trexio_hdf5.c)
list(APPEND TREXIO_PRIVATE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/trexio_hdf5.h)
# - define symbol HAVE_HDF5=1 (used to activate HDF5 back end in the preprocessor conditionals)
target_compile_definitions(trexio PUBLIC "HAVE_HDF5")
# - include directories with HDF5 header files
target_include_directories(trexio PRIVATE ${HDF5_C_INCLUDE_DIRS})
# - link to HDF5 C libraries
target_link_libraries(trexio PRIVATE
${HDF5_C_HL_LIBRARIES}
${HDF5_C_LIBRARIES})
endif()

# Private headers have to be listed as sources, otherwise they are installed
# with public headers upon make install (when using PRIVATE_HEADER property).
target_sources(trexio PRIVATE ${TREXIO_SOURCES} ${TREXIO_PRIVATE_HEADERS})

# ============= FORTRAN SUPPORT ==============

include(FortranCInterface)
# Check that C and Fortran compilers can talk to each other.
FortranCInterface_VERIFY()

# Fortran module
set(TREXIO_MOD_FILE ${CMAKE_SOURCE_DIR}/include/trexio_f.f90)
# Add TREXIO Fortran module as a library.
add_library(trexio_f SHARED)
target_sources(trexio_f PUBLIC ${TREXIO_MOD_FILE})
target_link_libraries(trexio_f PUBLIC trexio)

# ====== CODE GENERATION FOR DEVEL MODE =====

if(TREXIO_DEVEL)
set(ORG_FILES
templates_front/templator_front.org
templates_text/templator_text.org
${CMAKE_SOURCE_DIR}/trex.org
)
if(ENABLE_HDF5)
list(APPEND ORG_FILES templates_hdf5/templator_hdf5.org)
endif()

add_custom_command(OUTPUT
${TREXIO_SOURCES}
${TREXIO_PUBLIC_HEADERS}
${TREXIO_PRIVATE_HEADERS}
${TREXIO_MOD_FILE}
COMMAND ./build_trexio.sh
DEPENDS ${ORG_FILES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tools
COMMENT "Generating TREXIO source code from org-mode files."
VERBATIM)
endif()

# ============= INSTALL TREXIO ==============

include(GNUInstallDirs)
# Use standard GNU directories for installation of TREXIO (e.g. /usr/local/lib|include).
# The installation prefix can be modified using -DCMAKE_INSTALL_PREFIX=<custom/path> option of cmake.
install(TARGETS trexio
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# Also install trexio_f.f90 file with TREXIO Fortran module.
install(FILES ${TREXIO_MOD_FILE} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

# Uninstall target, copied from CMake FAQ:
# https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)

add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()

# ===========================================
Loading