Skip to content

Commit

Permalink
Update CMake build (crest-lab#272)
Browse files Browse the repository at this point in the history
Updated CMake build files.
Still needs some additions, but is already better than the old one.
  • Loading branch information
pprcht authored Mar 8, 2024
2 parents 7e3b360 + 1c76d44 commit a296392
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 262 deletions.
326 changes: 221 additions & 105 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,156 +10,272 @@
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with crest. If not, see <https://www.gnu.org/licenses/>.

cmake_minimum_required(VERSION 3.17)
option(WITH_OBJECT "To build using object library" TRUE)
option(INSTALL_MODULES "Install Fortran module files to include directory." FALSE)

cmake_minimum_required(VERSION 3.14)
# Buggy CMake versions
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.27.0 AND CMAKE_VERSION VERSION_LESS 3.28.0)
set(WITH_OBJECT FALSE)
endif()

# Setup the crest Project
project(
"crest"
LANGUAGES "Fortran" "C"
VERSION "3.0"
crest
LANGUAGES "C" "Fortran"
VERSION 3.0
DESCRIPTION "A tool for the exploration of low-energy chemical space"
)
set(SOVERSION "pre")

#enable_testing()

# Follow GNU conventions for installing directories
include(GNUInstallDirs)

# General configuration information
set(libs)
# Include further configurations
add_subdirectory("config")


#
# Libraries
#
###############################################################################
####################### SUBPROJECTS & DEPENDENCIES ############################
###############################################################################
# Check a specific CMake targets and execute the
# corresponding Find scripts (located in config/modules/)

# OpenMP dependency
if(NOT TARGET OpenMP::OpenMP_Fortran AND WITH_OpenMP)
find_package(OpenMP REQUIRED)
list(
APPEND libs
OpenMP::OpenMP_Fortran
)
# LAPACK, BLAS, OpenMP (usually via shared dependencies)
if(STATICBUILD)
set(BLA_STATIC ON)
endif()

# BLAS and LAPACK
if(NOT TARGET BLAS::BLAS)
find_package(BLAS REQUIRED)
if(NOT TARGET BLAS::BLAS AND BLAS_FOUND)
add_library(BLAS::BLAS INTERFACE IMPORTED)
target_link_libraries(BLAS::BLAS INTERFACE "${BLAS_LIBRARIES}")
target_link_options(BLAS::BLAS INTERFACE "${BLAS_LINKER_FLAGS}")
endif()
find_package(LAPACK REQUIRED)
find_package(BLAS REQUIRED)
if(NOT TARGET "OpenMP::OpenMP_Fortran" AND WITH_OpenMP)
find_package("OpenMP" REQUIRED)
endif()
if(NOT TARGET LAPACK::LAPACK)
find_package(LAPACK REQUIRED)
if(NOT TARGET LAPACK::LAPACK AND LAPACK_FOUND)
add_library(LAPACK::LAPACK INTERFACE IMPORTED)
target_link_libraries(LAPACK::LAPACK INTERFACE "${LAPACK_LIBRARIES}")
target_link_options(LAPACK::LAPACK INTERFACE "${LAPACK_LINKER_FLAGS}")
endif()

# TOML-F (needs to be imported before tblite)
if(NOT TARGET "toml-f::toml-f" AND WITH_TOMLF)
find_package("toml-f" REQUIRED)
add_compile_definitions(WITH_TOMLF)
endif()
list(
APPEND libs
LAPACK::LAPACK
BLAS::BLAS
)

# tblite
if(WITH_TBLITE)
find_package("tblite" REQUIRED)
add_definitions(-DWITH_TBLITE)
list(
APPEND libs
tblite::tblite
)
if(NOT TARGET "tblite::tblite" AND WITH_TBLITE)
find_package("tblite" REQUIRED)
add_compile_definitions(WITH_TBLITE)
endif()

# GFN-FF
if(NOT TARGET "gfnff::gfnff" AND WITH_GFNFF)
find_package("gfnff" REQUIRED)
add_compile_definitions(WITH_GFNFF)
endif()

# toml-f
if(WITH_TOMLF)
find_package("toml-f" REQUIRED)
add_definitions(-DWITH_TOMLF)
list(
APPEND libs
toml-f::toml-f
)
# GFN0-xTB
if(NOT TARGET "gfn0::gfn0" AND WITH_GFN0)
find_package("gfn0" REQUIRED)
add_compile_definitions(WITH_GFN0)
endif()

# XHCFF
if(NOT TARGET "xhcff::xhcff" AND WITH_XHCFF)
find_package("xhcff" REQUIRED)
add_compile_definitions(WITH_XHCFF)
endif()

# GFN0-xTB
if(WITH_GFN0)
find_package("gfn0" REQUIRED)
add_definitions(-DWITH_GFN0)
list(
APPEND libs
gfn0::gfn0
)
# lwONIOM
if(NOT TARGET "lwoniom::lwoniom" AND WITH_LWONIOM)
find_package("lwoniom" REQUIRED)
add_compile_definitions(WITH_LWONIOM)
endif()

# Sources: initialize program sources (prog) and library sources (srcs) empty
set(prog)
set(srcs)
add_subdirectory("src")

# GFN-FF
if(WITH_GFNFF)
find_package("gfnff" REQUIRED)
add_definitions(-DWITH_GFNFF)
list(
APPEND libs
gfnff::gfnff
)

if(NOT EXISTS "${PROJECT_BINARY_DIR}/include")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/include")
endif()

# XHCFF
if(WITH_XHCFF)
find_package("xhcff" REQUIRED)
add_definitions(-DWITH_XHCFF)
list(
APPEND libs
xhcff::xhcff
)
###############################################################################
########################## OBJECT LIBRARY #####################################
###############################################################################
if(WITH_OBJECT AND NOT STATICBUILD)

add_library(
"${PROJECT_NAME}-object"
OBJECT
${srcs}
)

# customize object library
set_target_properties(
"${PROJECT_NAME}-object"
PROPERTIES
Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include"
POSITION_INDEPENDENT_CODE ON
)

# link object library conditionally against required
target_link_libraries(
"${PROJECT_NAME}-object"
PUBLIC
$<$<BOOL:${WITH_TBLITE}>:tblite::tblite>
$<$<BOOL:${WITH_GFN0}>:gfn0::gfn0>
$<$<BOOL:${WITH_GFNFF}>:gfnff::gfnff>
$<$<BOOL:${WITH_XHCFF}>:xhcff::xhcff>
$<$<BOOL:${WITH_TOMLF}>:toml-f::toml-f>
$<$<BOOL:${WITH_LWONIOM}>:lwoniom::lwoniom>
$<$<BOOL:${WITH_OpenMP}>:OpenMP::OpenMP_Fortran>
)

# include directories
target_include_directories(
"${PROJECT_NAME}-object"
PUBLIC
${crest-config-dir}
${PROJECT_BINARY_DIR}
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>
)

endif()

###############################################################################
############################### Static Library ################################
###############################################################################
if(WITH_OBJECT AND NOT STATICBUILD)
add_library(
"lib-${PROJECT_NAME}-static"
STATIC
$<TARGET_OBJECTS:${PROJECT_NAME}-object>
)
else()
add_library(
"lib-${PROJECT_NAME}-static"
STATIC
${srcs}
)
endif()

# workaround attemp. doesn't work yet
set(LINK_OpenMP FALSE)
if(WITH_OpenMP AND NOT STATICBUILD)
set(LINK_OpenMP TRUE)
endif()

target_link_libraries(
"lib-${PROJECT_NAME}-static"
PUBLIC
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
$<$<BOOL:${LINK_OpenMP}>:OpenMP::OpenMP_Fortran>
$<$<BOOL:${WITH_TBLITE}>:tblite::tblite>
$<$<BOOL:${WITH_GFN0}>:gfn0::gfn0>
$<$<BOOL:${WITH_GFNFF}>:gfnff::gfnff>
$<$<BOOL:${WITH_XHCFF}>:xhcff::xhcff>
$<$<BOOL:${WITH_TOMLF}>:toml-f::toml-f>
$<$<BOOL:${WITH_LWONIOM}>:lwoniom::lwoniom>
$<$<BOOL:${STATICBUILD}>:-static>
)

#
# CREST sources
#
set(prog)
set(srcs)
add_subdirectory("src")

set_target_properties(
"lib-${PROJECT_NAME}-static"
PROPERTIES
Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include"
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
POSITION_INDEPENDENT_CODE ON
OUTPUT_NAME "${PROJECT_NAME}"
)

#
# Executables
#

target_include_directories(
"lib-${PROJECT_NAME}-static"
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>
)


####################################################################################
############################# Shared Library #######################################
####################################################################################
if (WITH_OBJECT AND NOT STATICBUILD)
add_library(
"lib-${PROJECT_NAME}-shared"
SHARED
$<TARGET_OBJECTS:${PROJECT_NAME}-object>
)

target_link_libraries(
"lib-${PROJECT_NAME}-shared"
PUBLIC
${BLAS_LIBRARIES}
${LAPACK_LIBRARIES}
$<$<BOOL:${WITH_OpenMP}>:OpenMP::OpenMP_Fortran>
$<$<BOOL:${WITH_TBLITE}>:tblite::tblite>
$<$<BOOL:${WITH_GFN0}>:gfn0::gfn0>
$<$<BOOL:${WITH_GFNFF}>:gfnff::gfnff>
$<$<BOOL:${WITH_XHCFF}>:xhcff::xhcff>
$<$<BOOL:${WITH_TOMLF}>:toml-f::toml-f>
$<$<BOOL:${WITH_LWONIOM}>:lwoniom::lwoniom>
)

set_target_properties(
"lib-${PROJECT_NAME}-shared"
PROPERTIES
Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include"
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}"
OUTPUT_NAME "${PROJECT_NAME}"
VERSION "${PROJECT_VERSION}"
SOVERSION "${PROJECT_VERSION_MAJOR}"
)

target_include_directories(
"lib-${PROJECT_NAME}-shared"
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>
)
endif()

###############################################################################
############################### Executables ###################################
###############################################################################
add_executable(
${PROJECT_NAME}-exe
"${srcs}" "${prog}"
${prog}
)

target_link_libraries(
${PROJECT_NAME}-exe
PRIVATE
"lib-${PROJECT_NAME}-static"
$<$<BOOL:${STATICBUILD}>:-static>
)

set_target_properties(
${PROJECT_NAME}-exe
PROPERTIES
Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/include
RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}
OUTPUT_NAME "${PROJECT_NAME}"
)
target_link_libraries(
${PROJECT_NAME}-exe
PRIVATE
"${libs}"
)

get_target_property(OUT ${PROJECT_NAME}-exe LINK_LIBRARIES)
message(STATUS ${OUT})

#
# Binary installing option
#
install(
TARGETS
"${PROJECT_NAME}-exe"
EXPORT
"${PROJECT_NAME}-targets"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
target_include_directories(
${PROJECT_NAME}-exe
PRIVATE
${PROJECT_SOURCE_DIR}/include
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
)

Loading

0 comments on commit a296392

Please sign in to comment.