From 04a1ad5624aa9d087dc848d5e874e61055d9e684 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Thu, 19 Nov 2020 17:11:44 -0800 Subject: [PATCH 01/21] WIP: Adding CMake. --- CMakeLists.txt | 61 +++++++++++++++++++++++++++++++ src/CMakeLists.txt | 7 ++++ src/clients/CMakeLists.txt | 11 ++++++ src/core/CMakeLists.txt | 63 +++++++++++++++++++++++++++++++++ src/ext/CMakeLists.txt | 3 ++ src/ext/auxparse/CMakeLists.txt | 7 ++++ src/ext/genesis/CMakeLists.txt | 31 ++++++++++++++++ src/ext/genmath/CMakeLists.txt | 23 ++++++++++++ src/lib/CMakeLists.txt | 22 ++++++++++++ 9 files changed, 228 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt create mode 100644 src/clients/CMakeLists.txt create mode 100644 src/core/CMakeLists.txt create mode 100644 src/ext/CMakeLists.txt create mode 100644 src/ext/auxparse/CMakeLists.txt create mode 100644 src/ext/genesis/CMakeLists.txt create mode 100644 src/ext/genmath/CMakeLists.txt create mode 100644 src/lib/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..ecf70bc4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,61 @@ +# Minimum cmake version +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) + +# Project name +project(SRW) + +# Folder for helper modules (Find*.cmake) +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + +# Uncomment for VERBOSE Makefiles. Useful for debugging. +set(CMAKE_VERBOSE_MAKEFILE ON) + +# Option for OpenMP build, OFF by default. +option(USE_OPENMP "Activate OpenMP build" OFF) + +# Option for Client libraries to be built or not - See src/clients/CMakeLists.txt +option(BUILD_CLIENTS "Activate Client libraries build" OFF) + +# Option for C client library to be built or not - See src/clients/CMakeLists.txt +option(BUILD_CLIENT_C "Activate C Client library build" OFF) + +# Option for Python client library to be built or not - See src/clients/CMakeLists.txt +option(BUILD_CLIENT_PYTHON "Activate Python Client library build" OFF) + +# Option for Igor Pro client library to be built or not - See src/clients/CMakeLists.txt +option(BUILD_CLIENT_IGOR "Activate Igor Pro Client library build" OFF) + +# Temporary path for FFTW in case we need to build it +set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) + +add_subdirectory(ext_lib) + +# OS Dependent configurations +if(UNIX) + if (APPLE) # MacOS + add_definitions(-D__MAC__) + else() # Linux + add_definitions(-DLINUX) + endif() +else() # Windows + add_definitions(-DWIN32) +endif() + +# Add definitions needed to build SRW +add_definitions(-D_GNU_SOURCE -D__USE_XOPEN2K8 -DFFTW_ENABLE_FLOAT) +add_definitions(-D_GM_WITHOUT_BASE -DSRWLIB_STATIC -DNO_TIMER) +add_definitions(-DANSI_DECLARATORS -DTRILIBRARY) + +if(USE_OPENMP) + add_definitions(-D_WITH_OMP) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp -Wno-write-strings") + set(USE_FFTW3 OFF) + #LDFLAGS += -lfftw +else() + add_definitions(-D_FFTW3) + set(USE_FFTW3 ON) + #LDFLAGS+= -lfftw3f -lfftw3 +endif() + +# Main source directory +add_subdirectory(src) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..7476071b --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(ext) +add_subdirectory(core) +add_subdirectory(lib) + +if(BUILD_CLIENTS) + add_subdirectory(clients) +endif() \ No newline at end of file diff --git a/src/clients/CMakeLists.txt b/src/clients/CMakeLists.txt new file mode 100644 index 00000000..ec94c26d --- /dev/null +++ b/src/clients/CMakeLists.txt @@ -0,0 +1,11 @@ +if(BUILD_CLIENT_C) + add_subdirectory(c) +endif() + +if(BUILD_CLIENT_PYTHON) + add_subdirectory(python) +endif() + +if(BUILD_CLIENT_IGOR) + add_subdirectory(igor) +endif() \ No newline at end of file diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 00000000..45c749b5 --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,63 @@ +set(core_source_files + srclcuti.cpp + srcradint.cpp + srctrjdt.cpp + sremitpr.cpp + srgsnbm.cpp + srgtrjdt.cpp + srisosrc.cpp + srmagcnt.cpp + srmagfld.cpp + srmatsta.cpp + sroptapt.cpp + sroptcnt.cpp + sroptdrf.cpp + sroptel2.cpp + sroptel3.cpp + sroptelm.cpp + sroptfoc.cpp + sroptgrat.cpp + sroptgtr.cpp + sropthck.cpp + sroptcryst.cpp + sroptmat.cpp + sroptpsh.cpp + sroptshp.cpp + sroptsmr.cpp + sroptwgr.cpp + sroptzp.cpp + sroptzps.cpp + srpersto.cpp + srpowden.cpp + srprdint.cpp + srprgind.cpp + srpropme.cpp + srptrjdt.cpp + srradinc.cpp + srradint.cpp + srradmnp.cpp + srradstr.cpp + srremflp.cpp + srsase.cpp + srsend.cpp + srstowig.cpp + srsysuti.cpp + srthckbm.cpp + srthckbm2.cpp + srtrjaux.cpp + srtrjdat.cpp + srtrjdat3d.cpp +) + +add_library(core ${core_source_files}) + +if (USE_FFTW3) + target_link_libraries(core auxparse genmath fftw fftwf) +else() + target_link_libraries(core auxparse genmath fftw) +endif() + +target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(core PUBLIC + $ +) \ No newline at end of file diff --git a/src/ext/CMakeLists.txt b/src/ext/CMakeLists.txt new file mode 100644 index 00000000..a9722d07 --- /dev/null +++ b/src/ext/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(auxparse) +add_subdirectory(genmath) +add_subdirectory(genesis) \ No newline at end of file diff --git a/src/ext/auxparse/CMakeLists.txt b/src/ext/auxparse/CMakeLists.txt new file mode 100644 index 00000000..f8bf85f4 --- /dev/null +++ b/src/ext/auxparse/CMakeLists.txt @@ -0,0 +1,7 @@ +set(auxparse_source_files + auxparse.cpp + auxparse.h +) + +add_library(auxparse ${auxparse_source_files}) +target_include_directories(auxparse PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/ext/genesis/CMakeLists.txt b/src/ext/genesis/CMakeLists.txt new file mode 100644 index 00000000..77d637ff --- /dev/null +++ b/src/ext/genesis/CMakeLists.txt @@ -0,0 +1,31 @@ +set(genesis_source_files + all_com.c + check.c + diagno.c + esource.c + field.c + incoherent.c + initrun.c + input.c + loadbeam.c + loadrad.c + magfield.c + main.c + math.c + mpi.c + output.c + partsim.c + pushp.c + rpos.c + scan.c + source.c + stepz.c + string.c + tdepend.c + timerec.c + track.c +) + +add_library(genesis ${genesis_source_files}) +target_link_libraries(genesis genmath) +target_include_directories(genesis PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file diff --git a/src/ext/genmath/CMakeLists.txt b/src/ext/genmath/CMakeLists.txt new file mode 100644 index 00000000..946fba67 --- /dev/null +++ b/src/ext/genmath/CMakeLists.txt @@ -0,0 +1,23 @@ +set(genmath_source_files + gmfft.cpp + gmfft.h + gmfit.cpp + gmfit.h + gminterp.cpp + gminterp.h + gmmeth.cpp + gmmeth.h + gmtrans.cpp + gmtrans.h +) + +add_library(genmath ${genmath_source_files}) + +if (USE_FFTW3) + target_link_libraries(genmath auxparse fftw fftwf) +else() + target_link_libraries(genmath auxparse fftw) +endif() + + +target_include_directories(genmath PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100644 index 00000000..6d760741 --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,22 @@ +set(srw_lib_source_files + srwlib.cpp + srwlib.h +) + +add_library(srwlib ${srw_lib_source_files}) + +if (USE_FFTW3) + target_link_libraries(srwlib auxparse genmath genesis core fftw fftwf) +else() + find_package(FFTW CONFIG REQUIRED) + get_property(_loc TARGET FFTW::fftw PROPERTY LOCATION) + message(STATUS "Found FFTW: ${_loc} (found version ${FFTW_VERSION})") + target_link_libraries(srwlib auxparse genmath genesis core FFTW::fftw) +endif() + +target_include_directories(srwlib PUBLIC + $ +) +target_include_directories(srwlib PUBLIC + $ +) \ No newline at end of file From 5d4c328db78f908d7739fbf03956df8899fc27a6 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Mon, 23 Nov 2020 15:24:18 -0800 Subject: [PATCH 02/21] ENH: First version building the python library as well. Currently the .so segfaults at import time. --- .gitignore | 1 - CMakeLists.txt | 52 ++--- cmake/FindFFTW.cmake | 339 ++++++++++++++++++++++++++++++ ext_lib/CMakeLists.txt | 1 + ext_lib/fftw3/CMakeLists.txt | 37 ++++ src/CMakeLists.txt | 44 ++++ src/clients/python/CMakeLists.txt | 44 ++++ src/core/CMakeLists.txt | 10 +- src/ext/auxparse/CMakeLists.txt | 2 +- src/ext/genesis/CMakeLists.txt | 2 +- src/ext/genmath/CMakeLists.txt | 11 +- src/lib/CMakeLists.txt | 44 ++-- 12 files changed, 531 insertions(+), 56 deletions(-) create mode 100644 cmake/FindFFTW.cmake create mode 100644 ext_lib/CMakeLists.txt create mode 100644 ext_lib/fftw3/CMakeLists.txt create mode 100644 src/clients/python/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 5ba184ca..bd6b0c90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -ext_lib docs/source/cookbook docs/build/ *.pyc diff --git a/CMakeLists.txt b/CMakeLists.txt index ecf70bc4..9bb6889f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,11 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) # Project name -project(SRW) +project(SRW LANGUAGES C) + +cmake_policy(SET CMP0074 NEW) + +include(GNUInstallDirs) # Folder for helper modules (Find*.cmake) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) @@ -27,35 +31,35 @@ option(BUILD_CLIENT_IGOR "Activate Igor Pro Client library build" OFF) # Temporary path for FFTW in case we need to build it set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) +message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") +# External Libraries add_subdirectory(ext_lib) -# OS Dependent configurations -if(UNIX) - if (APPLE) # MacOS - add_definitions(-D__MAC__) - else() # Linux - add_definitions(-DLINUX) - endif() -else() # Windows - add_definitions(-DWIN32) -endif() - -# Add definitions needed to build SRW -add_definitions(-D_GNU_SOURCE -D__USE_XOPEN2K8 -DFFTW_ENABLE_FLOAT) -add_definitions(-D_GM_WITHOUT_BASE -DSRWLIB_STATIC -DNO_TIMER) -add_definitions(-DANSI_DECLARATORS -DTRILIBRARY) - if(USE_OPENMP) - add_definitions(-D_WITH_OMP) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp -Wno-write-strings") - set(USE_FFTW3 OFF) + set(CORE_DEPENDS fftw_external) #LDFLAGS += -lfftw else() - add_definitions(-D_FFTW3) - set(USE_FFTW3 ON) + set(CORE_DEPENDS fftw3_external) #LDFLAGS+= -lfftw3f -lfftw3 endif() -# Main source directory -add_subdirectory(src) \ No newline at end of file +include(ExternalProject) +ExternalProject_Add(${PROJECT_NAME}_core + DEPENDS + ${CORE_DEPENDS} + SOURCE_DIR + ${CMAKE_CURRENT_LIST_DIR}/src + CMAKE_ARGS + -DFFTW_ROOT=${FFTW_ROOT} + -DBUILD_CLIENTS=${BUILD_CLIENTS} + -DBUILD_CLIENT_PYTHON=${BUILD_CLIENT_PYTHON} + -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} + CMAKE_CACHE_ARGS + -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} + -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH} + BUILD_ALWAYS + 1 + INSTALL_COMMAND + "" + ) diff --git a/cmake/FindFFTW.cmake b/cmake/FindFFTW.cmake new file mode 100644 index 00000000..8b7ef3c0 --- /dev/null +++ b/cmake/FindFFTW.cmake @@ -0,0 +1,339 @@ +# - Find the FFTW library +# +# Original version of this file: +# Copyright (c) 2015, Wenzel Jakob +# https://github.com/wjakob/layerlab/blob/master/cmake/FindFFTW.cmake, commit 4d58bfdc28891b4f9373dfe46239dda5a0b561c6 +# Modifications: +# Copyright (c) 2017, Patrick Bos +# +# Usage: +# find_package(FFTW [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX] ) +# +# It sets the following variables: +# FFTW_FOUND ... true if fftw is found on the system +# FFTW_[component]_LIB_FOUND ... true if the component is found on the system (see components below) +# FFTW_LIBRARIES ... full paths to all found fftw libraries +# FFTW_[component]_LIB ... full path to one of the components (see below) +# FFTW_INCLUDE_DIRS ... fftw include directory paths +# +# The following variables will be checked by the function +# FFTW_USE_STATIC_LIBS ... if true, only static libraries are found, otherwise both static and shared. +# FFTW_ROOT ... if set, the libraries are exclusively searched +# under this path +# +# This package supports the following components: +# FLOAT_LIB +# DOUBLE_LIB +# LONGDOUBLE_LIB +# FLOAT_THREADS_LIB +# DOUBLE_THREADS_LIB +# LONGDOUBLE_THREADS_LIB +# FLOAT_OPENMP_LIB +# DOUBLE_OPENMP_LIB +# LONGDOUBLE_OPENMP_LIB +# + +# TODO (maybe): extend with ExternalProject download + build option +# TODO: put on conda-forge + + +if( NOT FFTW_ROOT AND DEFINED ENV{FFTWDIR} ) + set( FFTW_ROOT $ENV{FFTWDIR} ) +endif() + +# Check if we can use PkgConfig +find_package(PkgConfig) + +#Determine from PKG +if( PKG_CONFIG_FOUND AND NOT FFTW_ROOT ) + pkg_check_modules( PKG_FFTW QUIET "fftw3" ) +endif() + +#Check whether to search static or dynamic libs +set( CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES} ) + +if( ${FFTW_USE_STATIC_LIBS} ) + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX} ) +else() + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} ) +endif() + +if( FFTW_ROOT ) + # find libs + + find_library( + FFTW_DOUBLE_LIB + NAMES "fftw3" libfftw3-3 + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_DOUBLE_THREADS_LIB + NAMES "fftw3_threads" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_DOUBLE_OPENMP_LIB + NAMES "fftw3_omp" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_FLOAT_LIB + NAMES "fftw3f" libfftw3f-3 + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_FLOAT_THREADS_LIB + NAMES "fftw3f_threads" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_FLOAT_OPENMP_LIB + NAMES "fftw3f_omp" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_LONGDOUBLE_LIB + NAMES "fftw3l" libfftw3l-3 + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_LONGDOUBLE_THREADS_LIB + NAMES "fftw3l_threads" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_LONGDOUBLE_OPENMP_LIB + NAMES "fftw3l_omp" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + #find includes + find_path(FFTW_INCLUDE_DIRS + NAMES "fftw3.h" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "include" + NO_DEFAULT_PATH + ) + +else() + + find_library( + FFTW_DOUBLE_LIB + NAMES "fftw3" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library( + FFTW_DOUBLE_THREADS_LIB + NAMES "fftw3_threads" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library( + FFTW_DOUBLE_OPENMP_LIB + NAMES "fftw3_omp" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library( + FFTW_FLOAT_LIB + NAMES "fftw3f" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library( + FFTW_FLOAT_THREADS_LIB + NAMES "fftw3f_threads" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library( + FFTW_FLOAT_OPENMP_LIB + NAMES "fftw3f_omp" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library( + FFTW_LONGDOUBLE_LIB + NAMES "fftw3l" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library( + FFTW_LONGDOUBLE_THREADS_LIB + NAMES "fftw3l_threads" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_library(FFTW_LONGDOUBLE_OPENMP_LIB + NAMES "fftw3l_omp" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + ) + + find_path(FFTW_INCLUDE_DIRS + NAMES "fftw3.h" + PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR} + ) + +endif( FFTW_ROOT ) + +#--------------------------------------- components + +if (FFTW_DOUBLE_LIB) + set(FFTW_DOUBLE_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_LIB}) + add_library(FFTW::Double INTERFACE IMPORTED) + set_target_properties(FFTW::Double + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_DOUBLE_LIB}" + ) +else() + set(FFTW_DOUBLE_LIB_FOUND FALSE) +endif() + +if (FFTW_FLOAT_LIB) + set(FFTW_FLOAT_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_LIB}) + add_library(FFTW::Float INTERFACE IMPORTED) + set_target_properties(FFTW::Float + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_FLOAT_LIB}" + ) +else() + set(FFTW_FLOAT_LIB_FOUND FALSE) +endif() + +if (FFTW_LONGDOUBLE_LIB) + set(FFTW_LONGDOUBLE_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_LIB}) + add_library(FFTW::LongDouble INTERFACE IMPORTED) + set_target_properties(FFTW::LongDouble + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_LONGDOUBLE_LIB}" + ) +else() + set(FFTW_LONGDOUBLE_LIB_FOUND FALSE) +endif() + +if (FFTW_DOUBLE_THREADS_LIB) + set(FFTW_DOUBLE_THREADS_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_THREADS_LIB}) + add_library(FFTW::DoubleThreads INTERFACE IMPORTED) + set_target_properties(FFTW::DoubleThreads + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_DOUBLETHREADS_LIB}" + ) +else() + set(FFTW_DOUBLE_THREADS_LIB_FOUND FALSE) +endif() + +if (FFTW_FLOAT_THREADS_LIB) + set(FFTW_FLOAT_THREADS_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_THREADS_LIB}) + add_library(FFTW::FloatThreads INTERFACE IMPORTED) + set_target_properties(FFTW::FloatThreads + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_FLOAT_THREADS_LIB}" + ) +else() + set(FFTW_FLOAT_THREADS_LIB_FOUND FALSE) +endif() + +if (FFTW_LONGDOUBLE_THREADS_LIB) + set(FFTW_LONGDOUBLE_THREADS_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_THREADS_LIB}) + add_library(FFTW::LongDoubleThreads INTERFACE IMPORTED) + set_target_properties(FFTW::LongDoubleThreads + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_LONGDOUBLE_THREADS_LIB}" + ) +else() + set(FFTW_LONGDOUBLE_THREADS_LIB_FOUND FALSE) +endif() + +if (FFTW_DOUBLE_OPENMP_LIB) + set(FFTW_DOUBLE_OPENMP_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_OPENMP_LIB}) + add_library(FFTW::DoubleOpenMP INTERFACE IMPORTED) + set_target_properties(FFTW::DoubleOpenMP + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_DOUBLE_OPENMP_LIB}" + ) +else() + set(FFTW_DOUBLE_OPENMP_LIB_FOUND FALSE) +endif() + +if (FFTW_FLOAT_OPENMP_LIB) + set(FFTW_FLOAT_OPENMP_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_OPENMP_LIB}) + add_library(FFTW::FloatOpenMP INTERFACE IMPORTED) + set_target_properties(FFTW::FloatOpenMP + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_FLOAT_OPENMP_LIB}" + ) +else() + set(FFTW_FLOAT_OPENMP_LIB_FOUND FALSE) +endif() + +if (FFTW_LONGDOUBLE_OPENMP_LIB) + set(FFTW_LONGDOUBLE_OPENMP_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_OPENMP_LIB}) + add_library(FFTW::LongDoubleOpenMP INTERFACE IMPORTED) + set_target_properties(FFTW::LongDoubleOpenMP + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_LONGDOUBLE_OPENMP_LIB}" + ) +else() + set(FFTW_LONGDOUBLE_OPENMP_LIB_FOUND FALSE) +endif() + +#--------------------------------------- end components + +set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} ) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(FFTW + REQUIRED_VARS FFTW_INCLUDE_DIRS + HANDLE_COMPONENTS + ) + +mark_as_advanced( + FFTW_INCLUDE_DIRS + FFTW_LIBRARIES + FFTW_FLOAT_LIB + FFTW_DOUBLE_LIB + FFTW_LONGDOUBLE_LIB + FFTW_FLOAT_THREADS_LIB + FFTW_DOUBLE_THREADS_LIB + FFTW_LONGDOUBLE_THREADS_LIB + FFTW_FLOAT_OPENMP_LIB + FFTW_DOUBLE_OPENMP_LIB + FFTW_LONGDOUBLE_OPENMP_LIB + ) diff --git a/ext_lib/CMakeLists.txt b/ext_lib/CMakeLists.txt new file mode 100644 index 00000000..fe8feab1 --- /dev/null +++ b/ext_lib/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(fftw3) \ No newline at end of file diff --git a/ext_lib/fftw3/CMakeLists.txt b/ext_lib/fftw3/CMakeLists.txt new file mode 100644 index 00000000..241f30f5 --- /dev/null +++ b/ext_lib/fftw3/CMakeLists.txt @@ -0,0 +1,37 @@ +find_package(FFTW QUIET COMPONENTS FLOAT_LIB DOUBLE_LIB) + +if(FFTW_FOUND) + message(STATUS "Found FFTW3: ${FFTW_DOUBLE_LIB}") + message(STATUS "Found FFTW3F: ${FFTW_FLOAT_LIB}") + add_library(fftw3_external INTERFACE) # dummy +else() + message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") + + include(ExternalProject) + ExternalProject_Add(fftw3_external + URL + http://www.fftw.org/fftw-3.3.8.tar.gz + URL_HASH + MD5=8aac833c943d8e90d51b697b27d4384d + PREFIX ${CMAKE_CURRENT_BINARY_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND + ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/configure --enable-float --with-pic --prefix=${STAGED_INSTALL_PREFIX} && + make -j8 && + make install && + make clean && + ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/configure --with-pic --prefix=${STAGED_INSTALL_PREFIX} && + make -j8 && + make install + INSTALL_COMMAND "" + PREFIX=${CMAKE_CURRENT_BINARY_DIR} + ) + + include(GNUInstallDirs) + + set( + FFTW_ROOT ${STAGED_INSTALL_PREFIX} + CACHE PATH "Path to internally built FFTW3Config.cmake" + FORCE + ) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7476071b..ce2e7333 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,47 @@ +project(SRW_core) +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) + +cmake_policy(SET CMP0074 NEW) + +# Uncomment for VERBOSE Makefiles. Useful for debugging. +set(CMAKE_VERBOSE_MAKEFILE ON) + +# Folder for helper modules (Find*.cmake) +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../cmake" ${CMAKE_MODULE_PATH}) + +include(GNUInstallDirs) + + +# OS Dependent configurations +if(UNIX) + if (APPLE) # MacOS + add_definitions(-D__MAC__) + else() # Linux + add_definitions(-DLINUX) + endif() +else() # Windows + add_definitions(-DWIN32) +endif() + +# Add definitions needed to build SRW +add_definitions(-D_GNU_SOURCE -D__USE_XOPEN2K8 -DFFTW_ENABLE_FLOAT) +add_definitions(-D_GM_WITHOUT_BASE -DSRWLIB_STATIC -DNO_TIMER) +add_definitions(-DANSI_DECLARATORS -DTRILIBRARY) + +if(USE_OPENMP) + add_definitions(-D_WITH_OMP) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp -Wno-write-strings") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp -Wno-write-strings") + set(USE_FFTW3 OFF) + #LDFLAGS += -lfftw +else() + add_definitions(-D_FFTW3) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + set(USE_FFTW3 ON) + #LDFLAGS+= -lfftw3f -lfftw3 +endif() + add_subdirectory(ext) add_subdirectory(core) add_subdirectory(lib) diff --git a/src/clients/python/CMakeLists.txt b/src/clients/python/CMakeLists.txt new file mode 100644 index 00000000..05bad70f --- /dev/null +++ b/src/clients/python/CMakeLists.txt @@ -0,0 +1,44 @@ +set(srw_clients_python_source_files + srwlpy.cpp +) + +add_library(srwlpy SHARED ${srw_clients_python_source_files}) + +# for testing we will need the python interpreter +find_package(PythonInterp REQUIRED) + +# we require python development headers +find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED) + +target_link_libraries(srwlpy srw ${PYTHON_LIBRARIES}) + +target_include_directories(srwlpy PRIVATE + ${PYTHON_INCLUDE_DIRS} +) + +target_include_directories(srwlpy PUBLIC + $ +) + +# prevent cmake from creating a "lib" prefix +set_target_properties(srwlpy + PROPERTIES + PREFIX "" +) + +if(WIN32) + # python will not import dll but expects pyd + set_target_properties(srwlpy + PROPERTIES + SUFFIX ".pyd" + ) +endif() +if(UNIX) + # python will not import dll but expects pyd + set_target_properties(srwlpy + PROPERTIES + SUFFIX ".so" + ) +endif() + +install(TARGETS srwlpy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) \ No newline at end of file diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 45c749b5..3b61623f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -49,14 +49,8 @@ set(core_source_files srtrjdat3d.cpp ) -add_library(core ${core_source_files}) - -if (USE_FFTW3) - target_link_libraries(core auxparse genmath fftw fftwf) -else() - target_link_libraries(core auxparse genmath fftw) -endif() - +add_library(core OBJECT ${core_source_files}) +target_link_libraries(core genesis) target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(core PUBLIC $ diff --git a/src/ext/auxparse/CMakeLists.txt b/src/ext/auxparse/CMakeLists.txt index f8bf85f4..da763196 100644 --- a/src/ext/auxparse/CMakeLists.txt +++ b/src/ext/auxparse/CMakeLists.txt @@ -3,5 +3,5 @@ set(auxparse_source_files auxparse.h ) -add_library(auxparse ${auxparse_source_files}) +add_library(auxparse OBJECT ${auxparse_source_files}) target_include_directories(auxparse PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/ext/genesis/CMakeLists.txt b/src/ext/genesis/CMakeLists.txt index 77d637ff..c1b869d1 100644 --- a/src/ext/genesis/CMakeLists.txt +++ b/src/ext/genesis/CMakeLists.txt @@ -26,6 +26,6 @@ set(genesis_source_files track.c ) -add_library(genesis ${genesis_source_files}) +add_library(genesis OBJECT ${genesis_source_files}) target_link_libraries(genesis genmath) target_include_directories(genesis PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file diff --git a/src/ext/genmath/CMakeLists.txt b/src/ext/genmath/CMakeLists.txt index 946fba67..c67a0c27 100644 --- a/src/ext/genmath/CMakeLists.txt +++ b/src/ext/genmath/CMakeLists.txt @@ -11,13 +11,6 @@ set(genmath_source_files gmtrans.h ) -add_library(genmath ${genmath_source_files}) - -if (USE_FFTW3) - target_link_libraries(genmath auxparse fftw fftwf) -else() - target_link_libraries(genmath auxparse fftw) -endif() - - +add_library(genmath OBJECT ${genmath_source_files}) +target_link_libraries(genmath PUBLIC auxparse) target_include_directories(genmath PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 6d760741..e93092b3 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -1,22 +1,42 @@ set(srw_lib_source_files srwlib.cpp srwlib.h + srerror.cpp + srerror.h ) -add_library(srwlib ${srw_lib_source_files}) +add_library(srw STATIC + ${srw_lib_source_files} + $ + $ + $ + $ +) + +find_package(FFTW REQUIRED COMPONENTS FLOAT_LIB DOUBLE_LIB) +message(STATUS "Found FFTW3: ${FFTW_DOUBLE_LIB}") +message(STATUS "Found FFTW3F: ${FFTW_FLOAT_LIB}") + + +target_link_libraries(srw PUBLIC core m FFTW::Float FFTW::Double) + +set(LINK_FLAGS ${LINK_FLAGS} "-Wl,-whole-archive") -if (USE_FFTW3) - target_link_libraries(srwlib auxparse genmath genesis core fftw fftwf) -else() - find_package(FFTW CONFIG REQUIRED) - get_property(_loc TARGET FFTW::fftw PROPERTY LOCATION) - message(STATUS "Found FFTW: ${_loc} (found version ${FFTW_VERSION})") - target_link_libraries(srwlib auxparse genmath genesis core FFTW::fftw) -endif() -target_include_directories(srwlib PUBLIC +target_include_directories(srw PUBLIC $ ) -target_include_directories(srwlib PUBLIC +target_include_directories(srw PUBLIC $ -) \ No newline at end of file +) +target_include_directories(srw PUBLIC + $ +) +target_include_directories(srw PUBLIC + $ +) +target_include_directories(srw PUBLIC + $ +) + +install(TARGETS srw LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) \ No newline at end of file From f0a1b467009d53309b4f3cb29b85d16c763e2ede Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Mon, 23 Nov 2020 16:05:01 -0800 Subject: [PATCH 03/21] ENH: Add support to build C client. --- CMakeLists.txt | 1 + src/clients/c/CMakeLists.txt | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/clients/c/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bb6889f..e3d1871f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ ExternalProject_Add(${PROJECT_NAME}_core -DFFTW_ROOT=${FFTW_ROOT} -DBUILD_CLIENTS=${BUILD_CLIENTS} -DBUILD_CLIENT_PYTHON=${BUILD_CLIENT_PYTHON} + -DBUILD_CLIENT_C=${BUILD_CLIENT_C} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} CMAKE_CACHE_ARGS -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} diff --git a/src/clients/c/CMakeLists.txt b/src/clients/c/CMakeLists.txt new file mode 100644 index 00000000..207924fc --- /dev/null +++ b/src/clients/c/CMakeLists.txt @@ -0,0 +1,13 @@ +set(srw_clients_c_source_files + srwlclient.cpp +) + +add_executable(srwlclient ${srw_clients_c_source_files}) + +target_link_libraries(srwlclient srw) + +target_include_directories(srwlclient PUBLIC + $ +) + +install(TARGETS srwlclient RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) \ No newline at end of file From 21838387d80a8afb4b401f8b363b5adfe98806ae Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Mon, 30 Nov 2020 16:26:31 -0800 Subject: [PATCH 04/21] MNT: Python build working properly. --- src/CMakeLists.txt | 7 +++---- src/clients/python/CMakeLists.txt | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce2e7333..a8998cc8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,16 +28,15 @@ add_definitions(-D_GNU_SOURCE -D__USE_XOPEN2K8 -DFFTW_ENABLE_FLOAT) add_definitions(-D_GM_WITHOUT_BASE -DSRWLIB_STATIC -DNO_TIMER) add_definitions(-DANSI_DECLARATORS -DTRILIBRARY) +add_compile_options(-fPIC) + if(USE_OPENMP) add_definitions(-D_WITH_OMP) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp -Wno-write-strings") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp -Wno-write-strings") + add_compile_options(-fopenmp -Wno-write-strings) set(USE_FFTW3 OFF) #LDFLAGS += -lfftw else() add_definitions(-D_FFTW3) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") set(USE_FFTW3 ON) #LDFLAGS+= -lfftw3f -lfftw3 endif() diff --git a/src/clients/python/CMakeLists.txt b/src/clients/python/CMakeLists.txt index 05bad70f..b85aa2f6 100644 --- a/src/clients/python/CMakeLists.txt +++ b/src/clients/python/CMakeLists.txt @@ -10,7 +10,9 @@ find_package(PythonInterp REQUIRED) # we require python development headers find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED) -target_link_libraries(srwlpy srw ${PYTHON_LIBRARIES}) +target_link_libraries(srwlpy srw) + +set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") target_include_directories(srwlpy PRIVATE ${PYTHON_INCLUDE_DIRS} From 8cb411c3f54d050b936949841180aca4159b916d Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Tue, 1 Dec 2020 10:41:06 -0800 Subject: [PATCH 05/21] MNT: Simplify CMake by removing the ExternalProject_add to deal with FFTW3 build dependency. --- CMakeLists.txt | 36 ++++++---------------------------- ext_lib/fftw3/CMakeLists.txt | 38 ++++++++++++++++++++++++++++++++++-- src/CMakeLists.txt | 14 ------------- src/lib/CMakeLists.txt | 7 +------ 4 files changed, 43 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3d1871f..4435f99d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) # Project name -project(SRW LANGUAGES C) +project(SRW) cmake_policy(SET CMP0074 NEW) @@ -14,6 +14,8 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) # Uncomment for VERBOSE Makefiles. Useful for debugging. set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_INSTALL_MESSAGE ALWAYS) + # Option for OpenMP build, OFF by default. option(USE_OPENMP "Activate OpenMP build" OFF) @@ -34,33 +36,7 @@ set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") # External Libraries -add_subdirectory(ext_lib) - -if(USE_OPENMP) - set(CORE_DEPENDS fftw_external) - #LDFLAGS += -lfftw -else() - set(CORE_DEPENDS fftw3_external) - #LDFLAGS+= -lfftw3f -lfftw3 -endif() +add_subdirectory(ext_lib/fftw3) -include(ExternalProject) -ExternalProject_Add(${PROJECT_NAME}_core - DEPENDS - ${CORE_DEPENDS} - SOURCE_DIR - ${CMAKE_CURRENT_LIST_DIR}/src - CMAKE_ARGS - -DFFTW_ROOT=${FFTW_ROOT} - -DBUILD_CLIENTS=${BUILD_CLIENTS} - -DBUILD_CLIENT_PYTHON=${BUILD_CLIENT_PYTHON} - -DBUILD_CLIENT_C=${BUILD_CLIENT_C} - -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} - CMAKE_CACHE_ARGS - -DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} - -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH} - BUILD_ALWAYS - 1 - INSTALL_COMMAND - "" - ) +# Main library +add_subdirectory(src) \ No newline at end of file diff --git a/ext_lib/fftw3/CMakeLists.txt b/ext_lib/fftw3/CMakeLists.txt index 241f30f5..c31f6519 100644 --- a/ext_lib/fftw3/CMakeLists.txt +++ b/ext_lib/fftw3/CMakeLists.txt @@ -3,7 +3,19 @@ find_package(FFTW QUIET COMPONENTS FLOAT_LIB DOUBLE_LIB) if(FFTW_FOUND) message(STATUS "Found FFTW3: ${FFTW_DOUBLE_LIB}") message(STATUS "Found FFTW3F: ${FFTW_FLOAT_LIB}") - add_library(fftw3_external INTERFACE) # dummy + + set( + FFTW_DOUBLE_LIB ${FFTW_DOUBLE_LIB} + CACHE PATH "Path to FFTW" + FORCE + ) + + set( + FFTW_FLOAT_LIB ${FFTW_FLOAT_LIB} + CACHE PATH "Path to FFTWF" + FORCE + ) + else() message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") @@ -33,5 +45,27 @@ else() FFTW_ROOT ${STAGED_INSTALL_PREFIX} CACHE PATH "Path to internally built FFTW3Config.cmake" FORCE - ) + ) + + set( + FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw3.a + CACHE PATH "Path to FFTW" + FORCE + ) + + set( + FFTW_FLOAT_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a + CACHE PATH "Path to FFTWF" + FORCE + ) + + # Libraries + add_library(fftw3 STATIC IMPORTED) + set_property(TARGET fftw3 PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3.a) + add_library(fftw3f STATIC IMPORTED) + set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a) + + add_dependencies(fftw3 fftw3_external) + add_dependencies(fftw3f fftw3_external) + endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a8998cc8..00abe96c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,17 +1,3 @@ -project(SRW_core) -cmake_minimum_required(VERSION 3.5 FATAL_ERROR) - -cmake_policy(SET CMP0074 NEW) - -# Uncomment for VERBOSE Makefiles. Useful for debugging. -set(CMAKE_VERBOSE_MAKEFILE ON) - -# Folder for helper modules (Find*.cmake) -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../cmake" ${CMAKE_MODULE_PATH}) - -include(GNUInstallDirs) - - # OS Dependent configurations if(UNIX) if (APPLE) # MacOS diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index e93092b3..5c405660 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -13,12 +13,7 @@ add_library(srw STATIC $ ) -find_package(FFTW REQUIRED COMPONENTS FLOAT_LIB DOUBLE_LIB) -message(STATUS "Found FFTW3: ${FFTW_DOUBLE_LIB}") -message(STATUS "Found FFTW3F: ${FFTW_FLOAT_LIB}") - - -target_link_libraries(srw PUBLIC core m FFTW::Float FFTW::Double) +target_link_libraries(srw PUBLIC core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) set(LINK_FLAGS ${LINK_FLAGS} "-Wl,-whole-archive") From ccfbf5a8541b2739722c91df8d57a1d656592ff4 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Tue, 1 Dec 2020 10:41:42 -0800 Subject: [PATCH 06/21] ENH: Make python setup.py use CMake for the build. --- python/setup.py | 80 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/python/setup.py b/python/setup.py index bc4afa2a..10e8a08a 100644 --- a/python/setup.py +++ b/python/setup.py @@ -1,25 +1,58 @@ import os -from setuptools import setup, find_packages, Extension - -ext_kwargs = {'define_macros': [('MAJOR_VERSION', '1'), ('MINOR_VERSION', '0')], - 'include_dirs': [os.path.abspath('../src/lib')], - 'library_dirs': [os.path.abspath('../src'), os.path.abspath('../ext_lib')], - 'sources': [os.path.abspath('../src/clients/python/srwlpy.cpp')]} - -if 'MODE' in os.environ: - sMode = str(os.environ['MODE']) - if sMode == 'omp': - ext_kwargs.update({'libraries': ['srw', 'm', 'fftw'], #OC07022019 - 'extra_link_args': ['-fopenmp'], - 'extra_compile_args': ['-Wno-sign-compare','-Wno-parentheses','-fopenmp','-Wno-write-strings']}) - elif sMode == '0': - ext_kwargs.update({'libraries': ['srw', 'm', 'fftw3f', 'fftw3']}) #OC07022019 - else: - raise Exception("Unknown SRW compilation/linking option") - -srwlpy = Extension('srwlpy', **ext_kwargs) - -setup(name='SRW Python interface', +import re +import sys +import subprocess + +from distutils.version import LooseVersion +from setuptools import setup, Extension, find_packages +from setuptools.command.build_ext import build_ext + + +class CMakeExtension(Extension): + def __init__(self, name, sourcedir=''): + Extension.__init__(self, name, sources=[]) + self.sourcedir = os.path.abspath(sourcedir) + + +class CMakeBuild(build_ext): + def run(self): + try: + out = subprocess.check_output(['cmake', '--version']) + except OSError: + raise RuntimeError( + "CMake must be installed to build the following extensions: " + + ", ".join(e.name for e in self.extensions)) + + cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', + out.decode()).group(1)) + if cmake_version < '3.5.0': + raise RuntimeError("CMake >= 3.5.0 is required.") + + for ext in self.extensions: + self.build_extension(ext) + + def build_extension(self, ext): + extdir = os.path.abspath( + os.path.dirname(self.get_ext_fullpath(ext.name))) + cmake_args = [ + '-DBUILD_CLIENTS=ON', + '-DBUILD_CLIENT_PYTHON=ON', + '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + '-DPYTHON_EXECUTABLE=' + sys.executable] + env = os.environ.copy() + if 'MODE' in env: + if env['MODE'] == 'omp': + cmake_args += ['-DUSE_OPENMP=ON'] + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + print('Using cmake args as: ', cmake_args) + subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, + cwd=self.build_temp, env=env) + subprocess.check_call(['cmake', '--build', '.'], + cwd=self.build_temp) + print() # Add an empty line for cleaner output + +setup(name='srwpy', version='1.0', description='This is SRW for Python', author='O. Chubar et al.', @@ -29,4 +62,7 @@ This is SRW for Python. ''', packages=find_packages(exclude=['docs', 'tests']), - ext_modules=[srwlpy]) + zip_safe=False, + ext_modules=[CMakeExtension('srwlpy', '..')], + cmdclass=dict(build_ext=CMakeBuild) +) From 44487ddb06527ca6a384064d184c1f49c09fbc93 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Tue, 1 Dec 2020 13:30:37 -0800 Subject: [PATCH 07/21] FIX: Add package name for proper installation of library compiled by CMake. --- python/setup.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/setup.py b/python/setup.py index 10e8a08a..8053eff7 100644 --- a/python/setup.py +++ b/python/setup.py @@ -9,9 +9,10 @@ class CMakeExtension(Extension): - def __init__(self, name, sourcedir=''): + def __init__(self, name, sourcedir='', package_name=''): Extension.__init__(self, name, sources=[]) self.sourcedir = os.path.abspath(sourcedir) + self.package_name = package_name class CMakeBuild(build_ext): @@ -34,6 +35,7 @@ def run(self): def build_extension(self, ext): extdir = os.path.abspath( os.path.dirname(self.get_ext_fullpath(ext.name))) + extdir = os.path.join(extdir, ext.package_name) cmake_args = [ '-DBUILD_CLIENTS=ON', '-DBUILD_CLIENT_PYTHON=ON', @@ -52,6 +54,9 @@ def build_extension(self, ext): cwd=self.build_temp) print() # Add an empty line for cleaner output +base_dir = os.path.dirname(os.path.realpath(__file__)) +original_src_dir = os.path.join(base_dir, '..') + setup(name='srwpy', version='1.0', description='This is SRW for Python', @@ -63,6 +68,6 @@ def build_extension(self, ext): ''', packages=find_packages(exclude=['docs', 'tests']), zip_safe=False, - ext_modules=[CMakeExtension('srwlpy', '..')], + ext_modules=[CMakeExtension('srwlpy', original_src_dir, 'srwpy')], cmdclass=dict(build_ext=CMakeBuild) ) From 3e2ec6a631a3b7c930d57dade0f208ae0e562c73 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Tue, 1 Dec 2020 14:12:16 -0800 Subject: [PATCH 08/21] FIX: Add documentation for Python client CMakeLists.txt file. --- src/clients/python/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/clients/python/CMakeLists.txt b/src/clients/python/CMakeLists.txt index b85aa2f6..f3aeb882 100644 --- a/src/clients/python/CMakeLists.txt +++ b/src/clients/python/CMakeLists.txt @@ -12,6 +12,8 @@ find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT RE target_link_libraries(srwlpy srw) +# We need the undefined dynamic_lookup to overcome issues with a statically linked +# python. More details here: https://gitlab.kitware.com/vtk/vtk/-/issues/17214 set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") target_include_directories(srwlpy PRIVATE From 979f23c34e4b3d0614fd399bc8191a78b3f36f5a Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Tue, 1 Dec 2020 14:18:41 -0800 Subject: [PATCH 09/21] FIX: Add more patterns and comments to .gitignore. --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index bd6b0c90..5069fa7e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,18 @@ +# Python build products +python/build/ +python/dist/ +python/srwpy.egg-info/ + +# Documentation artifacts docs/source/cookbook docs/build/ + +# Python and C compiled files *.pyc *.o data_example* .idea + +# Compiled libraries *.a *.so From 569b575ce20ce81a1fc8342132a03d5293066667 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Tue, 1 Dec 2020 14:53:43 -0800 Subject: [PATCH 10/21] FIX: Make sure FindFFTW also checks CONDA_PREFIX if available. --- cmake/FindFFTW.cmake | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/cmake/FindFFTW.cmake b/cmake/FindFFTW.cmake index 8b7ef3c0..9d594247 100644 --- a/cmake/FindFFTW.cmake +++ b/cmake/FindFFTW.cmake @@ -33,9 +33,6 @@ # LONGDOUBLE_OPENMP_LIB # -# TODO (maybe): extend with ExternalProject download + build option -# TODO: put on conda-forge - if( NOT FFTW_ROOT AND DEFINED ENV{FFTWDIR} ) set( FFTW_ROOT $ENV{FFTWDIR} ) @@ -146,59 +143,59 @@ else() find_library( FFTW_DOUBLE_LIB NAMES "fftw3" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library( FFTW_DOUBLE_THREADS_LIB NAMES "fftw3_threads" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library( FFTW_DOUBLE_OPENMP_LIB NAMES "fftw3_omp" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library( FFTW_FLOAT_LIB NAMES "fftw3f" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library( FFTW_FLOAT_THREADS_LIB NAMES "fftw3f_threads" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library( FFTW_FLOAT_OPENMP_LIB NAMES "fftw3f_omp" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library( FFTW_LONGDOUBLE_LIB NAMES "fftw3l" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library( FFTW_LONGDOUBLE_THREADS_LIB NAMES "fftw3l_threads" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_library(FFTW_LONGDOUBLE_OPENMP_LIB NAMES "fftw3l_omp" - PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib ) find_path(FFTW_INCLUDE_DIRS NAMES "fftw3.h" - PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR} + PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR} $ENV{CONDA_PREFIX}/include ) endif( FFTW_ROOT ) From dc42a1367edc0096e7f1f648cc40cd088ffe5a80 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Thu, 3 Dec 2020 18:03:43 -0800 Subject: [PATCH 11/21] ENH: Adding support for building OpenMP and FFTW2. --- CMakeLists.txt | 27 ++- cmake/FindFFTW2.cmake | 336 +++++++++++++++++++++++++++++++++ ext_lib/CMakeLists.txt | 8 +- ext_lib/fftw/CMakeLists.txt | 58 ++++++ src/CMakeLists.txt | 10 +- src/ext/genmath/CMakeLists.txt | 6 +- src/lib/CMakeLists.txt | 8 +- 7 files changed, 440 insertions(+), 13 deletions(-) create mode 100644 cmake/FindFFTW2.cmake create mode 100644 ext_lib/fftw/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 4435f99d..851355a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ # Minimum cmake version -cmake_minimum_required(VERSION 3.5 FATAL_ERROR) +# Picked 3.12 as this one introduces a proper FindOpenMP +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) # Project name project(SRW) @@ -14,7 +15,12 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) # Uncomment for VERBOSE Makefiles. Useful for debugging. set(CMAKE_VERBOSE_MAKEFILE ON) -set(CMAKE_INSTALL_MESSAGE ALWAYS) +# Useful debug for Find commands +#set(CMAKE_FIND_DEBUG_MODE ON) + +# Uncomment for install messages +#set(CMAKE_INSTALL_MESSAGE ALWAYS) + # Option for OpenMP build, OFF by default. option(USE_OPENMP "Activate OpenMP build" OFF) @@ -31,12 +37,25 @@ option(BUILD_CLIENT_PYTHON "Activate Python Client library build" OFF) # Option for Igor Pro client library to be built or not - See src/clients/CMakeLists.txt option(BUILD_CLIENT_IGOR "Activate Igor Pro Client library build" OFF) + # Temporary path for FFTW in case we need to build it set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") +# Force FFTW to look for STATIC libraries that we need +set(FFTW_USE_STATIC_LIBS ON) + # External Libraries -add_subdirectory(ext_lib/fftw3) +add_subdirectory(ext_lib) # Main library -add_subdirectory(src) \ No newline at end of file +add_subdirectory(src) + + + +# TODO: +#- Finish the Python package setup -> Done +#- Test with OpenMP and make adjustments (FFTW2, etc) -> Done +#- Test that +#- Test with Windows +#- Make sure Oleg's way still works with the VisualC++. diff --git a/cmake/FindFFTW2.cmake b/cmake/FindFFTW2.cmake new file mode 100644 index 00000000..676ba32c --- /dev/null +++ b/cmake/FindFFTW2.cmake @@ -0,0 +1,336 @@ +# - Find the FFTW2 library +# +# Original version of this file: +# Copyright (c) 2015, Wenzel Jakob +# https://github.com/wjakob/layerlab/blob/master/cmake/FindFFTW.cmake, commit 4d58bfdc28891b4f9373dfe46239dda5a0b561c6 +# Modifications: +# Copyright (c) 2017, Patrick Bos +# +# Usage: +# find_package(FFTW [REQUIRED] [QUIET] [COMPONENTS component1 ... componentX] ) +# +# It sets the following variables: +# FFTW2_FOUND ... true if fftw is found on the system +# FFTW_[component]_LIB_FOUND ... true if the component is found on the system (see components below) +# FFTW_LIBRARIES ... full paths to all found fftw libraries +# FFTW_[component]_LIB ... full path to one of the components (see below) +# FFTW_INCLUDE_DIRS ... fftw include directory paths +# +# The following variables will be checked by the function +# FFTW_USE_STATIC_LIBS ... if true, only static libraries are found, otherwise both static and shared. +# FFTW_ROOT ... if set, the libraries are exclusively searched +# under this path +# +# This package supports the following components: +# FLOAT_LIB +# DOUBLE_LIB +# LONGDOUBLE_LIB +# FLOAT_THREADS_LIB +# DOUBLE_THREADS_LIB +# LONGDOUBLE_THREADS_LIB +# FLOAT_OPENMP_LIB +# DOUBLE_OPENMP_LIB +# LONGDOUBLE_OPENMP_LIB +# + + +if( NOT FFTW_ROOT AND DEFINED ENV{FFTWDIR} ) + set( FFTW_ROOT $ENV{FFTWDIR} ) +endif() + +# Check if we can use PkgConfig +find_package(PkgConfig) + +#Determine from PKG +if( PKG_CONFIG_FOUND AND NOT FFTW_ROOT ) + pkg_check_modules( PKG_FFTW QUIET "fftw" ) +endif() + +#Check whether to search static or dynamic libs +set( CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES} ) + +if( ${FFTW_USE_STATIC_LIBS} ) + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX} ) +else() + set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} ) +endif() + +if( FFTW_ROOT ) + # find libs + + find_library( + FFTW_DOUBLE_LIB + NAMES "fftw" libfftw + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_DOUBLE_THREADS_LIB + NAMES "fftw_threads" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_DOUBLE_OPENMP_LIB + NAMES "fftw_omp" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_FLOAT_LIB + NAMES "fftwf" libfftwf + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_FLOAT_THREADS_LIB + NAMES "fftwf_threads" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_FLOAT_OPENMP_LIB + NAMES "fftwf_omp" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_LONGDOUBLE_LIB + NAMES "fftwl" libfftwl + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_LONGDOUBLE_THREADS_LIB + NAMES "fftwl_threads" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + find_library( + FFTW_LONGDOUBLE_OPENMP_LIB + NAMES "fftwl_omp" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "lib" "lib64" + NO_DEFAULT_PATH + ) + + #find includes + find_path(FFTW_INCLUDE_DIRS + NAMES "fftw.h" + PATHS ${FFTW_ROOT} + PATH_SUFFIXES "include" + NO_DEFAULT_PATH + ) + +else() + + find_library( + FFTW_DOUBLE_LIB + NAMES "fftw" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library( + FFTW_DOUBLE_THREADS_LIB + NAMES "fftw_threads" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library( + FFTW_DOUBLE_OPENMP_LIB + NAMES "fftw_omp" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library( + FFTW_FLOAT_LIB + NAMES "fftwf" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library( + FFTW_FLOAT_THREADS_LIB + NAMES "fftwf_threads" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library( + FFTW_FLOAT_OPENMP_LIB + NAMES "fftwf_omp" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library( + FFTW_LONGDOUBLE_LIB + NAMES "fftwl" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library( + FFTW_LONGDOUBLE_THREADS_LIB + NAMES "fftwl_threads" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_library(FFTW_LONGDOUBLE_OPENMP_LIB + NAMES "fftwl_omp" + PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR} $ENV{CONDA_PREFIX}/lib + ) + + find_path(FFTW_INCLUDE_DIRS + NAMES "fftw.h" + PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR} $ENV{CONDA_PREFIX}/include + ) + +endif( FFTW_ROOT ) + +#--------------------------------------- components + +if (FFTW_DOUBLE_LIB) + set(FFTW_DOUBLE_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_LIB}) + add_library(FFTW::Double INTERFACE IMPORTED) + set_target_properties(FFTW::Double + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_DOUBLE_LIB}" + ) +else() + set(FFTW_DOUBLE_LIB_FOUND FALSE) +endif() + +if (FFTW_FLOAT_LIB) + set(FFTW_FLOAT_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_LIB}) + add_library(FFTW::Float INTERFACE IMPORTED) + set_target_properties(FFTW::Float + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_FLOAT_LIB}" + ) +else() + set(FFTW_FLOAT_LIB_FOUND FALSE) +endif() + +if (FFTW_LONGDOUBLE_LIB) + set(FFTW_LONGDOUBLE_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_LIB}) + add_library(FFTW::LongDouble INTERFACE IMPORTED) + set_target_properties(FFTW::LongDouble + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_LONGDOUBLE_LIB}" + ) +else() + set(FFTW_LONGDOUBLE_LIB_FOUND FALSE) +endif() + +if (FFTW_DOUBLE_THREADS_LIB) + set(FFTW_DOUBLE_THREADS_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_THREADS_LIB}) + add_library(FFTW::DoubleThreads INTERFACE IMPORTED) + set_target_properties(FFTW::DoubleThreads + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_DOUBLETHREADS_LIB}" + ) +else() + set(FFTW_DOUBLE_THREADS_LIB_FOUND FALSE) +endif() + +if (FFTW_FLOAT_THREADS_LIB) + set(FFTW_FLOAT_THREADS_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_THREADS_LIB}) + add_library(FFTW::FloatThreads INTERFACE IMPORTED) + set_target_properties(FFTW::FloatThreads + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_FLOAT_THREADS_LIB}" + ) +else() + set(FFTW_FLOAT_THREADS_LIB_FOUND FALSE) +endif() + +if (FFTW_LONGDOUBLE_THREADS_LIB) + set(FFTW_LONGDOUBLE_THREADS_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_THREADS_LIB}) + add_library(FFTW::LongDoubleThreads INTERFACE IMPORTED) + set_target_properties(FFTW::LongDoubleThreads + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_LONGDOUBLE_THREADS_LIB}" + ) +else() + set(FFTW_LONGDOUBLE_THREADS_LIB_FOUND FALSE) +endif() + +if (FFTW_DOUBLE_OPENMP_LIB) + set(FFTW_DOUBLE_OPENMP_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_DOUBLE_OPENMP_LIB}) + add_library(FFTW::DoubleOpenMP INTERFACE IMPORTED) + set_target_properties(FFTW::DoubleOpenMP + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_DOUBLE_OPENMP_LIB}" + ) +else() + set(FFTW_DOUBLE_OPENMP_LIB_FOUND FALSE) +endif() + +if (FFTW_FLOAT_OPENMP_LIB) + set(FFTW_FLOAT_OPENMP_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_FLOAT_OPENMP_LIB}) + add_library(FFTW::FloatOpenMP INTERFACE IMPORTED) + set_target_properties(FFTW::FloatOpenMP + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_FLOAT_OPENMP_LIB}" + ) +else() + set(FFTW_FLOAT_OPENMP_LIB_FOUND FALSE) +endif() + +if (FFTW_LONGDOUBLE_OPENMP_LIB) + set(FFTW_LONGDOUBLE_OPENMP_LIB_FOUND TRUE) + set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTW_LONGDOUBLE_OPENMP_LIB}) + add_library(FFTW::LongDoubleOpenMP INTERFACE IMPORTED) + set_target_properties(FFTW::LongDoubleOpenMP + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FFTW_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFTW_LONGDOUBLE_OPENMP_LIB}" + ) +else() + set(FFTW_LONGDOUBLE_OPENMP_LIB_FOUND FALSE) +endif() + +#--------------------------------------- end components + +set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} ) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(FFTW2 + REQUIRED_VARS FFTW_INCLUDE_DIRS + HANDLE_COMPONENTS + ) + +mark_as_advanced( + FFTW_INCLUDE_DIRS + FFTW_LIBRARIES + FFTW_FLOAT_LIB + FFTW_DOUBLE_LIB + FFTW_LONGDOUBLE_LIB + FFTW_FLOAT_THREADS_LIB + FFTW_DOUBLE_THREADS_LIB + FFTW_LONGDOUBLE_THREADS_LIB + FFTW_FLOAT_OPENMP_LIB + FFTW_DOUBLE_OPENMP_LIB + FFTW_LONGDOUBLE_OPENMP_LIB + ) diff --git a/ext_lib/CMakeLists.txt b/ext_lib/CMakeLists.txt index fe8feab1..9eac7156 100644 --- a/ext_lib/CMakeLists.txt +++ b/ext_lib/CMakeLists.txt @@ -1 +1,7 @@ -add_subdirectory(fftw3) \ No newline at end of file +if(USE_OPENMP) + message(STATUS "Looking for FFTW2") + add_subdirectory(fftw) +else() + message(STATUS "Looking for FFTW3") + add_subdirectory(fftw3) +endif() \ No newline at end of file diff --git a/ext_lib/fftw/CMakeLists.txt b/ext_lib/fftw/CMakeLists.txt new file mode 100644 index 00000000..9a8dbcfb --- /dev/null +++ b/ext_lib/fftw/CMakeLists.txt @@ -0,0 +1,58 @@ +find_package(FFTW2 QUIET COMPONENTS FLOAT_LIB) + +if(FFTW2_FOUND) + message(STATUS "Found FFTW2F: ${FFTW_FLOAT_LIB}") + + set( + FFTW_DOUBLE_LIB ${FFTW_DOUBLE_LIB} + CACHE PATH "Path to FFTW" + FORCE + ) + +else() + message(STATUS "Suitable FFTW could not be located. Downloading and building!") + + include(ExternalProject) + ExternalProject_Add(fftw_external + URL + http://www.fftw.org/fftw-2.1.5.tar.gz + URL_HASH + MD5=8d16a84f3ca02a785ef9eb36249ba433 + PREFIX ${CMAKE_CURRENT_BINARY_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND + ${CMAKE_CURRENT_BINARY_DIR}/src/fftw_external/configure --enable-float --with-pic --prefix=${STAGED_INSTALL_PREFIX} && + make -j8 && + make install + INSTALL_COMMAND "" + PREFIX=${CMAKE_CURRENT_BINARY_DIR} + ) + + include(GNUInstallDirs) + + set( + FFTW_ROOT ${STAGED_INSTALL_PREFIX} + CACHE PATH "Path to internally built FFTWConfig.cmake" + FORCE + ) + + set( + FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw.a + CACHE PATH "Path to FFTW" + FORCE + ) + + set( + FFTW_FLOAT_LIB + CACHE PATH "Path to FFTWF" + FORCE + ) + + + # Libraries + add_library(fftw STATIC IMPORTED) + set_property(TARGET fftw PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw.a) + + add_dependencies(fftw fftw_external) + +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00abe96c..45c1c793 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,15 +16,15 @@ add_definitions(-DANSI_DECLARATORS -DTRILIBRARY) add_compile_options(-fPIC) +message(STATUS "Compiler is: ${CMAKE_C_COMPILER} | ${CMAKE_CXX_COMPILER}") + if(USE_OPENMP) + find_package(OpenMP REQUIRED) add_definitions(-D_WITH_OMP) - add_compile_options(-fopenmp -Wno-write-strings) - set(USE_FFTW3 OFF) - #LDFLAGS += -lfftw + message(STATUS "OpenMP libomp location: ${OpenMP_libomp_LIBRARY} | Include: ${OpenMP_CXX_INCLUDE_DIRS}") + message(STATUS "OpenMP Flags: C -> ${OpenMP_C_FLAGS} | CXX -> ${OpenMP_CXX_FLAGS}") else() add_definitions(-D_FFTW3) - set(USE_FFTW3 ON) - #LDFLAGS+= -lfftw3f -lfftw3 endif() add_subdirectory(ext) diff --git a/src/ext/genmath/CMakeLists.txt b/src/ext/genmath/CMakeLists.txt index c67a0c27..7abbb22b 100644 --- a/src/ext/genmath/CMakeLists.txt +++ b/src/ext/genmath/CMakeLists.txt @@ -13,4 +13,8 @@ set(genmath_source_files add_library(genmath OBJECT ${genmath_source_files}) target_link_libraries(genmath PUBLIC auxparse) -target_include_directories(genmath PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file +target_include_directories(genmath PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +if(USE_OPENMP) + target_include_directories(genmath PUBLIC ${OpenMP_CXX_INCLUDE_DIRS}) +endif() \ No newline at end of file diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 5c405660..b352131b 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -13,11 +13,15 @@ add_library(srw STATIC $ ) -target_link_libraries(srw PUBLIC core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) +if (USE_OPENMP) + target_link_libraries(srw PUBLIC core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB} OpenMP::OpenMP_CXX) + target_include_directories(srw PUBLIC ${OpenMP_CXX_INCLUDE_DIRS}) +else() + target_link_libraries(srw PUBLIC core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) +endif() set(LINK_FLAGS ${LINK_FLAGS} "-Wl,-whole-archive") - target_include_directories(srw PUBLIC $ ) From 8e32de3f19fce90a5156bdda68c167d83bc5df31 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Thu, 3 Dec 2020 18:04:14 -0800 Subject: [PATCH 12/21] MNT: adding build/ to .gitignore. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5069fa7e..041a66fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Build directory +build/ + # Python build products python/build/ python/dist/ From a2fbe146c52da4b5b84e7d1cfaedd83c3fb6eb39 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Thu, 10 Dec 2020 16:45:05 -0800 Subject: [PATCH 13/21] FIX: Apply patch for openmp from https://github.com/SergeyYakubov/SRW/archive/openmp_memoryfix. --- src/core/sroptel2.cpp | 32 ++++++++++++++++++++------------ src/core/sroptelm.cpp | 40 +++++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/src/core/sroptel2.cpp b/src/core/sroptel2.cpp index 42117619..95c21204 100644 --- a/src/core/sroptel2.cpp +++ b/src/core/sroptel2.cpp @@ -182,10 +182,13 @@ int srTGenOptElem::PropagateRadiationMeth_0(srTSRWRadStructAccessData* pRadAcces bool* gridParamWereModif = new bool[neOrig]; //SY: return outside of parallel regions is not allowed - we do it outside - - int* results = new int[neOrig]; - if(results == 0) return MEMORY_ALLOCATION_FAILURE; - for(int ie = 0; ie < neOrig; ie++) results[ie] = 0; + int* single_results = new int[neOrig]; + if(single_results == 0) return MEMORY_ALLOCATION_FAILURE; + int max_threads = omp_get_max_threads(); + int* thread_results = new int[max_threads]; + if(thread_results == 0) return MEMORY_ALLOCATION_FAILURE; + for(int ie = 0; ie < neOrig; ie++) single_results[ie] = 0; + for(int tn = 0; tn < max_threads; tn++) thread_results[tn] = 0; //OC31102018: added by SY (for profiling?) at parallelizing SRW via OpenMP //srwlPrintTime(": PropagateRadiationMeth_0 : before cycle",&start); @@ -201,15 +204,15 @@ int srTGenOptElem::PropagateRadiationMeth_0(srTSRWRadStructAccessData* pRadAcces { int threadNum = omp_get_thread_num(); srTSRWRadStructAccessData *pRadDataSingleE = 0; - results[threadNum] = SetupNewRadStructFromSliceConstE(pRadAccessData, -1, pRadDataSingleE); + thread_results[threadNum] = SetupNewRadStructFromSliceConstE(pRadAccessData, -1, pRadDataSingleE); //allocates new pRadDataSingleE ! - if(!results[threadNum]) + if(!thread_results[threadNum]) { #pragma omp for for(int ie=0; iepBaseRadX, pRadDataSingleE->pBaseRadZ)) continue; + if(single_results[ie] = ExtractRadSliceConstE(pRadAccessData, ie, pRadDataSingleE->pBaseRadX, pRadDataSingleE->pBaseRadZ)) continue; pRadDataSingleE->eStart = pRadAccessData->eStart + ie*pRadAccessData->eStep; long OffsetMom = AmOfMoments*ie; pRadDataSingleE->pMomX = pRadAccessData->pMomX + OffsetMom; @@ -231,7 +234,7 @@ int srTGenOptElem::PropagateRadiationMeth_0(srTSRWRadStructAccessData* pRadAcces if(pPrevRadDataSingleE != 0) { - if(results[ie] = ExtractRadSliceConstE(pRadAccessData, ie, pPrevRadDataSingleE->pBaseRadX, pPrevRadDataSingleE->pBaseRadZ, true)) continue; //OC120908 + if(single_results[ie] = ExtractRadSliceConstE(pRadAccessData, ie, pPrevRadDataSingleE->pBaseRadX, pPrevRadDataSingleE->pBaseRadZ, true)) continue; //OC120908 pPrevRadDataSingleE->eStart = pRadDataSingleE->eStart; pPrevRadDataSingleE->pMomX = pRadDataSingleE->pMomX; pPrevRadDataSingleE->pMomZ = pRadDataSingleE->pMomZ; @@ -239,9 +242,9 @@ int srTGenOptElem::PropagateRadiationMeth_0(srTSRWRadStructAccessData* pRadAcces //if(results[ie] = PropagateRadiationSingleE_Meth_0(pRadDataSingleE, pPrevRadDataSingleE, pBuf)) continue; //OC06092019 //OC01102019 (restored) - if(results[ie] = PropagateRadiationSingleE_Meth_0(pRadDataSingleE, pPrevRadDataSingleE)) continue; //from derived classes + if(single_results[ie] = PropagateRadiationSingleE_Meth_0(pRadDataSingleE, pPrevRadDataSingleE)) continue; //from derived classes - if(results[ie] = UpdateGenRadStructSliceConstE_Meth_0(pRadDataSingleE, ie, pRadAccessData, 1)) continue; + if(single_results[ie] = UpdateGenRadStructSliceConstE_Meth_0(pRadDataSingleE, ie, pRadAccessData, 1)) continue; //the above doesn't change the transverse grid parameters in *pRadAccessData //vRadSlices.push_back(*pRadDataSingleE); //this automatically calls destructor, which can eventually delete "emulated" structs! @@ -259,8 +262,13 @@ int srTGenOptElem::PropagateRadiationMeth_0(srTSRWRadStructAccessData* pRadAcces if(pRadDataSingleE != 0) delete pRadDataSingleE; } - for(int ie = 0; ie < neOrig; ie++) if(results[ie]) return results[ie]; - delete[] results; + // check results, free memory, exit if there was error + result = 0; + for(int ie = 0; ie < neOrig; ie++) if(single_results[ie]) result = single_results[ie]; + for(int tn = 0; tn < max_threads; tn++) if(thread_results[tn]) result = thread_results[tn]; + delete[] single_results; + delete[] thread_results; + if (result) return result; //OC31102018: added by SY (for profiling?) at parallelizing SRW via OpenMP //char str[256]; diff --git a/src/core/sroptelm.cpp b/src/core/sroptelm.cpp index 5bd83e8c..336d5567 100644 --- a/src/core/sroptelm.cpp +++ b/src/core/sroptelm.cpp @@ -1341,14 +1341,16 @@ int srTGenOptElem::SetRadRepres(srTSRWRadStructAccessData* pRadAccessData, char //} #else //OC28102018: modified by SY - //Added by SY (for profiling?) at parallelizing SRW via OpenMP: - //srwlPrintTime("SetRadRepres : setup",&start); - //SY: return outside of parallel regions is not allowed - we do it outside - int* results = new int[pRadAccessData->ne]; - if(results == 0) return MEMORY_ALLOCATION_FAILURE; - for(long ie = 0; ie < pRadAccessData->ne; ie++) results[ie]=0; + int* single_results = new int[pRadAccessData->ne]; + if(single_results == 0) return MEMORY_ALLOCATION_FAILURE; + for(long ie = 0; ie < pRadAccessData->ne; ie++) single_results[ie]=0; + + int max_threads = omp_get_max_threads(); + int* thread_results = new int[max_threads]; + if(thread_results == 0) return MEMORY_ALLOCATION_FAILURE; + for(int tn = 0; tn < max_threads; tn++) thread_results[tn] = 0; //SY: creation (and deletion) of FFTW plans is not thread-safe. Have to do this outside of threads. //(and we don't need to recreate plans for same dimensions anyway) @@ -1372,14 +1374,14 @@ int srTGenOptElem::SetRadRepres(srTSRWRadStructAccessData* pRadAccessData, char //members are changed inside Make2DFFT. CGenMathFFT2DInfo FFT2DInfo_local = FFT2DInfo; - if(results[ie] = ExtractRadSliceConstE(pRadAccessData, ie, AuxEx, AuxEz)) continue; + if(single_results[ie] = ExtractRadSliceConstE(pRadAccessData, ie, AuxEx, AuxEz)) continue; srTDataPtrsForWfrEdgeCorr DataPtrsForWfrEdgeCorr; if(WfrEdgeCorrShouldBeTreated) { if(CoordOrAng == 1) { - if(results[ie] = SetupWfrEdgeCorrData(pRadAccessData, AuxEx, AuxEz, DataPtrsForWfrEdgeCorr)) continue; + if(single_results[ie] = SetupWfrEdgeCorrData(pRadAccessData, AuxEx, AuxEz, DataPtrsForWfrEdgeCorr)) continue; } } @@ -1388,10 +1390,10 @@ int srTGenOptElem::SetRadRepres(srTSRWRadStructAccessData* pRadAccessData, char if(ar_zStartInSlicesE != 0) FFT2DInfo_local.yStart = ar_zStartInSlicesE[ie]; FFT2DInfo_local.pData = AuxEx; - if(results[ie] = FFT2D.Make2DFFT(FFT2DInfo_local, &Plan2DFFT)) continue; + if(single_results[ie] = FFT2D.Make2DFFT(FFT2DInfo_local, &Plan2DFFT)) continue; FFT2DInfo_local.pData = AuxEz; - if(results[ie] = FFT2D.Make2DFFT(FFT2DInfo_local, &Plan2DFFT)) continue; + if(single_results[ie] = FFT2D.Make2DFFT(FFT2DInfo_local, &Plan2DFFT)) continue; if(WfrEdgeCorrShouldBeTreated) { @@ -1404,14 +1406,14 @@ int srTGenOptElem::SetRadRepres(srTSRWRadStructAccessData* pRadAccessData, char } } } - results[ie] = SetupRadSliceConstE(pRadAccessData, ie, AuxEx, AuxEz); + single_results[ie] = SetupRadSliceConstE(pRadAccessData, ie, AuxEx, AuxEz); //SY: save FFT2DInfo from one of FFT2DInfo_local if(ie == 0) FFT2DInfo = FFT2DInfo_local; } // end for } else { - results[omp_get_thread_num()] = MEMORY_ALLOCATION_FAILURE; + thread_results[omp_get_thread_num()] = MEMORY_ALLOCATION_FAILURE; } // end if if(AuxEx != 0) delete[] AuxEx; if(AuxEz != 0) delete[] AuxEz; @@ -1420,16 +1422,16 @@ int srTGenOptElem::SetRadRepres(srTSRWRadStructAccessData* pRadAccessData, char fftwnd_destroy_plan(Plan2DFFT); - for(long ie = 0; ie < pRadAccessData->ne; ie++) if(results[ie]) return results[ie]; - delete[] results; + // check results, free memory, exit if there was error + result = 0; + for(long ie = 0; ie < pRadAccessData->ne; ie++) if(single_results[ie]) result = single_results[ie]; + for(int tn = 0; tn < max_threads; tn++) if(thread_results[tn]) result = thread_results[tn]; + delete[] single_results; + delete[] thread_results; + if (result) return result; #endif } - //Added by SY (for profiling?) at parallelizing SRW via OpenMP: - //char str[256]; - //sprintf(str,"%s %d","::SetRadRepres : cycles:",pRadAccessData->ne); - //srwlPrintTime(str,&start); - pRadAccessData->xStep = FFT2DInfo.xStepTr; pRadAccessData->zStep = FFT2DInfo.yStepTr; pRadAccessData->xStart = FFT2DInfo.xStartTr; From 07cd68a1e2d24f1e5761d7695571bcbbab1643cd Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Thu, 7 Jan 2021 10:23:40 -0800 Subject: [PATCH 14/21] FIX: First properly working version with OpenMP and FFTW2. --- CMakeLists.txt | 4 ++++ cmake/FindFFTW2.cmake | 1 - ext_lib/fftw/CMakeLists.txt | 15 ++++++++++----- python/setup.py | 4 ++-- src/CMakeLists.txt | 9 ++------- src/clients/python/CMakeLists.txt | 15 +++++++++------ src/core/CMakeLists.txt | 2 ++ src/ext/auxparse/CMakeLists.txt | 1 + src/ext/genesis/CMakeLists.txt | 3 ++- src/ext/genmath/CMakeLists.txt | 4 +++- src/lib/CMakeLists.txt | 10 ++++++---- 11 files changed, 41 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 851355a6..4aaf365b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,10 @@ set(CMAKE_VERBOSE_MAKEFILE ON) # Uncomment for install messages #set(CMAKE_INSTALL_MESSAGE ALWAYS) +# Uncomment for Debug Build +#set(CMAKE_BUILD_TYPE Debug) + +set(CMAKE_BUILD_TYPE Release) # Option for OpenMP build, OFF by default. option(USE_OPENMP "Activate OpenMP build" OFF) diff --git a/cmake/FindFFTW2.cmake b/cmake/FindFFTW2.cmake index 676ba32c..7039d575 100644 --- a/cmake/FindFFTW2.cmake +++ b/cmake/FindFFTW2.cmake @@ -33,7 +33,6 @@ # LONGDOUBLE_OPENMP_LIB # - if( NOT FFTW_ROOT AND DEFINED ENV{FFTWDIR} ) set( FFTW_ROOT $ENV{FFTWDIR} ) endif() diff --git a/ext_lib/fftw/CMakeLists.txt b/ext_lib/fftw/CMakeLists.txt index 9a8dbcfb..c7e9ae93 100644 --- a/ext_lib/fftw/CMakeLists.txt +++ b/ext_lib/fftw/CMakeLists.txt @@ -18,14 +18,19 @@ else() http://www.fftw.org/fftw-2.1.5.tar.gz URL_HASH MD5=8d16a84f3ca02a785ef9eb36249ba433 + CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} PREFIX ${CMAKE_CURRENT_BINARY_DIR} CONFIGURE_COMMAND "" - BUILD_COMMAND - ${CMAKE_CURRENT_BINARY_DIR}/src/fftw_external/configure --enable-float --with-pic --prefix=${STAGED_INSTALL_PREFIX} && - make -j8 && - make install + BUILD_COMMAND "" + # This cp line is important. FFTW 2 must be build inplace otherwise + # the make part will generate invalid library... + COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/src/fftw_external/ . + COMMAND ./configure --enable-float --with-pic + COMMAND sed -e "s/^CFLAGS = /CFLAGS = -fPIC /" -i "" Makefile + COMMAND make -j8 + COMMAND mkdir -p ${STAGED_INSTALL_PREFIX}/lib + COMMAND cp fftw/.libs/libfftw.a ${STAGED_INSTALL_PREFIX}/lib INSTALL_COMMAND "" - PREFIX=${CMAKE_CURRENT_BINARY_DIR} ) include(GNUInstallDirs) diff --git a/python/setup.py b/python/setup.py index 8053eff7..4f8041a5 100644 --- a/python/setup.py +++ b/python/setup.py @@ -26,8 +26,8 @@ def run(self): cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1)) - if cmake_version < '3.5.0': - raise RuntimeError("CMake >= 3.5.0 is required.") + if cmake_version < '3.12.0': + raise RuntimeError("CMake >= 3.12.0 is required.") for ext in self.extensions: self.build_extension(ext) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 45c1c793..acc656de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,22 +9,17 @@ else() # Windows add_definitions(-DWIN32) endif() -# Add definitions needed to build SRW -add_definitions(-D_GNU_SOURCE -D__USE_XOPEN2K8 -DFFTW_ENABLE_FLOAT) -add_definitions(-D_GM_WITHOUT_BASE -DSRWLIB_STATIC -DNO_TIMER) -add_definitions(-DANSI_DECLARATORS -DTRILIBRARY) - add_compile_options(-fPIC) message(STATUS "Compiler is: ${CMAKE_C_COMPILER} | ${CMAKE_CXX_COMPILER}") if(USE_OPENMP) find_package(OpenMP REQUIRED) - add_definitions(-D_WITH_OMP) message(STATUS "OpenMP libomp location: ${OpenMP_libomp_LIBRARY} | Include: ${OpenMP_CXX_INCLUDE_DIRS}") message(STATUS "OpenMP Flags: C -> ${OpenMP_C_FLAGS} | CXX -> ${OpenMP_CXX_FLAGS}") + set(SRW_DEFINITIONS -D_GNU_SOURCE -D__USE_XOPEN2K8 -DFFTW_ENABLE_FLOAT -D_GM_WITHOUT_BASE -DSRWLIB_STATIC -DNO_TIMER -DANSI_DECLARATORS -DTRILIBRARY -D_WITH_OMP) else() - add_definitions(-D_FFTW3) + set(SRW_DEFINITIONS -D_GNU_SOURCE -D__USE_XOPEN2K8 -DFFTW_ENABLE_FLOAT -D_GM_WITHOUT_BASE -DSRWLIB_STATIC -DNO_TIMER -DANSI_DECLARATORS -DTRILIBRARY -D_FFTW3) endif() add_subdirectory(ext) diff --git a/src/clients/python/CMakeLists.txt b/src/clients/python/CMakeLists.txt index f3aeb882..adfc0438 100644 --- a/src/clients/python/CMakeLists.txt +++ b/src/clients/python/CMakeLists.txt @@ -10,11 +10,7 @@ find_package(PythonInterp REQUIRED) # we require python development headers find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED) -target_link_libraries(srwlpy srw) - -# We need the undefined dynamic_lookup to overcome issues with a statically linked -# python. More details here: https://gitlab.kitware.com/vtk/vtk/-/issues/17214 -set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") +target_link_libraries(srwlpy srw m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) target_include_directories(srwlpy PRIVATE ${PYTHON_INCLUDE_DIRS} @@ -44,5 +40,12 @@ if(UNIX) SUFFIX ".so" ) endif() +if(APPLE) + # We need the undefined dynamic_lookup to overcome issues with a statically linked + # python. More details here: https://gitlab.kitware.com/vtk/vtk/-/issues/17214 + set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-undefined dynamic_lookup -shared") +else() + set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-shared") +endif() -install(TARGETS srwlpy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) \ No newline at end of file +install(TARGETS srwlpy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3b61623f..5dd800c9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -51,6 +51,8 @@ set(core_source_files add_library(core OBJECT ${core_source_files}) target_link_libraries(core genesis) +target_compile_definitions(core PRIVATE ${SRW_DEFINITIONS}) + target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(core PUBLIC $ diff --git a/src/ext/auxparse/CMakeLists.txt b/src/ext/auxparse/CMakeLists.txt index da763196..19c09e44 100644 --- a/src/ext/auxparse/CMakeLists.txt +++ b/src/ext/auxparse/CMakeLists.txt @@ -5,3 +5,4 @@ set(auxparse_source_files add_library(auxparse OBJECT ${auxparse_source_files}) target_include_directories(auxparse PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_compile_definitions(auxparse PRIVATE ${SRW_DEFINITIONS}) diff --git a/src/ext/genesis/CMakeLists.txt b/src/ext/genesis/CMakeLists.txt index c1b869d1..b522f629 100644 --- a/src/ext/genesis/CMakeLists.txt +++ b/src/ext/genesis/CMakeLists.txt @@ -28,4 +28,5 @@ set(genesis_source_files add_library(genesis OBJECT ${genesis_source_files}) target_link_libraries(genesis genmath) -target_include_directories(genesis PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file +target_include_directories(genesis PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_compile_definitions(genesis PRIVATE ${SRW_DEFINITIONS}) diff --git a/src/ext/genmath/CMakeLists.txt b/src/ext/genmath/CMakeLists.txt index 7abbb22b..41b1e776 100644 --- a/src/ext/genmath/CMakeLists.txt +++ b/src/ext/genmath/CMakeLists.txt @@ -17,4 +17,6 @@ target_include_directories(genmath PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) if(USE_OPENMP) target_include_directories(genmath PUBLIC ${OpenMP_CXX_INCLUDE_DIRS}) -endif() \ No newline at end of file +endif() + +target_compile_definitions(genmath PRIVATE ${SRW_DEFINITIONS}) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index b352131b..669a42c4 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -13,15 +13,17 @@ add_library(srw STATIC $ ) + +# Add definitions needed to build SRW +target_compile_definitions(srw PRIVATE ${SRW_DEFINITIONS}) + if (USE_OPENMP) - target_link_libraries(srw PUBLIC core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB} OpenMP::OpenMP_CXX) + target_link_libraries(srw PRIVATE core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB} OpenMP::OpenMP_CXX) target_include_directories(srw PUBLIC ${OpenMP_CXX_INCLUDE_DIRS}) else() - target_link_libraries(srw PUBLIC core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) + target_link_libraries(srw PRIVATE core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) endif() -set(LINK_FLAGS ${LINK_FLAGS} "-Wl,-whole-archive") - target_include_directories(srw PUBLIC $ ) From b25cf4dd5eb47a0a51ff8bab4efc57f37baff92c Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Thu, 7 Jan 2021 14:21:38 -0800 Subject: [PATCH 15/21] FIX: Adding compatibility between linux and mac. --- ext_lib/fftw/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext_lib/fftw/CMakeLists.txt b/ext_lib/fftw/CMakeLists.txt index c7e9ae93..625bd14c 100644 --- a/ext_lib/fftw/CMakeLists.txt +++ b/ext_lib/fftw/CMakeLists.txt @@ -24,9 +24,9 @@ else() BUILD_COMMAND "" # This cp line is important. FFTW 2 must be build inplace otherwise # the make part will generate invalid library... - COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/src/fftw_external/ . + COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/src/fftw_external/. . COMMAND ./configure --enable-float --with-pic - COMMAND sed -e "s/^CFLAGS = /CFLAGS = -fPIC /" -i "" Makefile + COMMAND sed -i.bak -e "s/^CFLAGS = /CFLAGS = -fPIC /" Makefile COMMAND make -j8 COMMAND mkdir -p ${STAGED_INSTALL_PREFIX}/lib COMMAND cp fftw/.libs/libfftw.a ${STAGED_INSTALL_PREFIX}/lib From 5023e97879e4792027eec13e4ef14a6e16e9a0f9 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Fri, 8 Jan 2021 09:58:29 -0800 Subject: [PATCH 16/21] WIP: Attempt to use precompiled FFTW3 from official source. --- ext_lib/fftw3/CMakeLists.txt | 106 +++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 41 deletions(-) diff --git a/ext_lib/fftw3/CMakeLists.txt b/ext_lib/fftw3/CMakeLists.txt index c31f6519..7a262f1a 100644 --- a/ext_lib/fftw3/CMakeLists.txt +++ b/ext_lib/fftw3/CMakeLists.txt @@ -17,54 +17,78 @@ if(FFTW_FOUND) ) else() - message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") + if(UNIX) + message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") - include(ExternalProject) - ExternalProject_Add(fftw3_external - URL - http://www.fftw.org/fftw-3.3.8.tar.gz - URL_HASH - MD5=8aac833c943d8e90d51b697b27d4384d - PREFIX ${CMAKE_CURRENT_BINARY_DIR} - CONFIGURE_COMMAND "" - BUILD_COMMAND - ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/configure --enable-float --with-pic --prefix=${STAGED_INSTALL_PREFIX} && - make -j8 && - make install && - make clean && - ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/configure --with-pic --prefix=${STAGED_INSTALL_PREFIX} && - make -j8 && - make install - INSTALL_COMMAND "" - PREFIX=${CMAKE_CURRENT_BINARY_DIR} - ) + include(ExternalProject) + ExternalProject_Add(fftw3_external + URL + http://www.fftw.org/fftw-3.3.8.tar.gz + URL_HASH + MD5=8aac833c943d8e90d51b697b27d4384d + PREFIX ${CMAKE_CURRENT_BINARY_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND + ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/configure --enable-float --with-pic --prefix=${STAGED_INSTALL_PREFIX} && + make -j8 && + make install && + make clean && + ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/configure --with-pic --prefix=${STAGED_INSTALL_PREFIX} && + make -j8 && + make install + INSTALL_COMMAND "" + PREFIX=${CMAKE_CURRENT_BINARY_DIR} + ) - include(GNUInstallDirs) + include(GNUInstallDirs) - set( - FFTW_ROOT ${STAGED_INSTALL_PREFIX} - CACHE PATH "Path to internally built FFTW3Config.cmake" - FORCE - ) + set( + FFTW_ROOT ${STAGED_INSTALL_PREFIX} + CACHE PATH "Path to internally built FFTW3Config.cmake" + FORCE + ) - set( - FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw3.a - CACHE PATH "Path to FFTW" - FORCE - ) + set( + FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw3.a + CACHE PATH "Path to FFTW" + FORCE + ) - set( - FFTW_FLOAT_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a - CACHE PATH "Path to FFTWF" - FORCE - ) + set( + FFTW_FLOAT_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a + CACHE PATH "Path to FFTWF" + FORCE + ) - # Libraries - add_library(fftw3 STATIC IMPORTED) - set_property(TARGET fftw3 PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3.a) - add_library(fftw3f STATIC IMPORTED) - set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a) + # Libraries + add_library(fftw3 STATIC IMPORTED) + set_property(TARGET fftw3 PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3.a) + add_library(fftw3f STATIC IMPORTED) + set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a) + endif() + if(WIN32) + message(STATUS "Suitable FFTW3 could not be located. Downloading precompiled library!") + include(ExternalProject) + ExternalProject_Add(fftw3_external + URL + ftp://ftp.fftw.org/pub/fftw/fftw-3.3.5-dll64.zip + URL_HASH + MD5=cb3c5ad19a89864f036e7a2dd5be168c + PREFIX ${CMAKE_CURRENT_BINARY_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND + xcopy /s ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external ${STAGED_INSTALL_PREFIX} + INSTALL_COMMAND "" + PREFIX=${CMAKE_CURRENT_BINARY_DIR} + ) + # Libraries + add_library(fftw3 STATIC IMPORTED) + set_property(TARGET fftw3 PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/libfftw3-3.dll) + add_library(fftw3f STATIC IMPORTED) + set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/libfftw3f-3.dll) + endif() + add_dependencies(fftw3 fftw3_external) add_dependencies(fftw3f fftw3_external) From efe4433977084b503b3d02f88f6f4bce6a5eb276 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Fri, 8 Jan 2021 10:18:49 -0800 Subject: [PATCH 17/21] WIP: Forgot to define some variables for the Win32 case. --- ext_lib/fftw3/CMakeLists.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ext_lib/fftw3/CMakeLists.txt b/ext_lib/fftw3/CMakeLists.txt index 7a262f1a..e468ac6d 100644 --- a/ext_lib/fftw3/CMakeLists.txt +++ b/ext_lib/fftw3/CMakeLists.txt @@ -82,13 +82,32 @@ else() PREFIX=${CMAKE_CURRENT_BINARY_DIR} ) + + set( + FFTW_ROOT ${STAGED_INSTALL_PREFIX} + CACHE PATH "Path to internally built FFTW3Config.cmake" + FORCE + ) + + set( + FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/libfftw3-3.dll + CACHE PATH "Path to FFTW" + FORCE + ) + + set( + FFTW_FLOAT_LIB ${STAGED_INSTALL_PREFIX}/libfftw3f-3.dll + CACHE PATH "Path to FFTWF" + FORCE + ) + # Libraries add_library(fftw3 STATIC IMPORTED) set_property(TARGET fftw3 PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/libfftw3-3.dll) add_library(fftw3f STATIC IMPORTED) set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/libfftw3f-3.dll) endif() - + add_dependencies(fftw3 fftw3_external) add_dependencies(fftw3f fftw3_external) From f1987bd1fc2c2380c153c912c27b825479504bf6 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Tue, 12 Jan 2021 21:38:04 -0800 Subject: [PATCH 18/21] FIX: Regular Windows build working. --- CMakeLists.txt | 30 ++++++++++------- ext_lib/fftw3/CMakeLists.txt | 24 +++++++------ python/setup.py | 9 ++++- src/CMakeLists.txt | 7 ++-- src/clients/python/CMakeLists.txt | 56 +++++++++++++------------------ src/lib/CMakeLists.txt | 14 +++++--- 6 files changed, 77 insertions(+), 63 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4aaf365b..9c1601a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,11 @@ project(SRW) cmake_policy(SET CMP0074 NEW) -include(GNUInstallDirs) - # Folder for helper modules (Find*.cmake) set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) # Uncomment for VERBOSE Makefiles. Useful for debugging. -set(CMAKE_VERBOSE_MAKEFILE ON) +#set(CMAKE_VERBOSE_MAKEFILE ON) # Useful debug for Find commands #set(CMAKE_FIND_DEBUG_MODE ON) @@ -23,7 +21,6 @@ set(CMAKE_VERBOSE_MAKEFILE ON) # Uncomment for Debug Build #set(CMAKE_BUILD_TYPE Debug) - set(CMAKE_BUILD_TYPE Release) # Option for OpenMP build, OFF by default. @@ -46,6 +43,22 @@ option(BUILD_CLIENT_IGOR "Activate Igor Pro Client library build" OFF) set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") + +if(UNIX) + # Use /lib /bin /include /share folder structure + include(GNUInstallDirs) +else() + if (WIN32) + set(${CMAKE_INSTALL_LIBDIR} "lib") + set(${CMAKE_INSTALL_DATADIR} "share") + set(${CMAKE_INSTALL_INCLUDEDIR} "include") + set(${CMAKE_INSTALL_BINDIR} "bin") + message(STATUS "Setting installation destination on Windows to: ${CMAKE_INSTALL_PREFIX}") + else() + message(FATAL_ERROR "System not UNIX nor WIN32 - not implemented yet") + endif() +endif() + # Force FFTW to look for STATIC libraries that we need set(FFTW_USE_STATIC_LIBS ON) @@ -54,12 +67,3 @@ add_subdirectory(ext_lib) # Main library add_subdirectory(src) - - - -# TODO: -#- Finish the Python package setup -> Done -#- Test with OpenMP and make adjustments (FFTW2, etc) -> Done -#- Test that -#- Test with Windows -#- Make sure Oleg's way still works with the VisualC++. diff --git a/ext_lib/fftw3/CMakeLists.txt b/ext_lib/fftw3/CMakeLists.txt index e468ac6d..62555176 100644 --- a/ext_lib/fftw3/CMakeLists.txt +++ b/ext_lib/fftw3/CMakeLists.txt @@ -67,21 +67,25 @@ else() set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a) endif() if(WIN32) - message(STATUS "Suitable FFTW3 could not be located. Downloading precompiled library!") + message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") include(ExternalProject) ExternalProject_Add(fftw3_external URL - ftp://ftp.fftw.org/pub/fftw/fftw-3.3.5-dll64.zip + http://www.fftw.org/fftw-3.3.8.tar.gz URL_HASH - MD5=cb3c5ad19a89864f036e7a2dd5be168c + MD5=8aac833c943d8e90d51b697b27d4384d PREFIX ${CMAKE_CURRENT_BINARY_DIR} CONFIGURE_COMMAND "" - BUILD_COMMAND - xcopy /s ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external ${STAGED_INSTALL_PREFIX} + BUILD_COMMAND "" + COMMAND cmake ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/ -DBUILD_SHARED_LIBS=OFF -DENABLE_FLOAT=ON -DBUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX} + COMMAND cmake --build . --config Release --target install + COMMAND cmake ${CMAKE_CURRENT_BINARY_DIR}/src/fftw3_external/ -DBUILD_SHARED_LIBS=OFF -DENABLE_FLOAT=OFF -DBUILD_TESTS=OFF-DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX} + COMMAND cmake --build . --config Release --target install INSTALL_COMMAND "" - PREFIX=${CMAKE_CURRENT_BINARY_DIR} ) + include(GNUInstallDirs) + set( FFTW_ROOT ${STAGED_INSTALL_PREFIX} @@ -90,22 +94,22 @@ else() ) set( - FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/libfftw3-3.dll + FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/fftw3.lib CACHE PATH "Path to FFTW" FORCE ) set( - FFTW_FLOAT_LIB ${STAGED_INSTALL_PREFIX}/libfftw3f-3.dll + FFTW_FLOAT_LIB ${STAGED_INSTALL_PREFIX}/lib/fftw3f.lib CACHE PATH "Path to FFTWF" FORCE ) # Libraries add_library(fftw3 STATIC IMPORTED) - set_property(TARGET fftw3 PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/libfftw3-3.dll) + set_property(TARGET fftw3 PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/fftw3.lib) add_library(fftw3f STATIC IMPORTED) - set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/libfftw3f-3.dll) + set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/fftw3f.lib) endif() add_dependencies(fftw3 fftw3_external) diff --git a/python/setup.py b/python/setup.py index 4f8041a5..417a234c 100644 --- a/python/setup.py +++ b/python/setup.py @@ -40,17 +40,24 @@ def build_extension(self, ext): '-DBUILD_CLIENTS=ON', '-DBUILD_CLIENT_PYTHON=ON', '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=' + extdir, '-DPYTHON_EXECUTABLE=' + sys.executable] env = os.environ.copy() if 'MODE' in env: if env['MODE'] == 'omp': cmake_args += ['-DUSE_OPENMP=ON'] + if os.name == 'nt': + # We need makefile generator that does not support multi-configuration builds + # otherwise windows will output a Release or Debug folder in which the artifacts + # will be located. + cmake_args.append('-GNMake Makefiles') + if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) print('Using cmake args as: ', cmake_args) subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env) - subprocess.check_call(['cmake', '--build', '.'], + subprocess.check_call(['cmake', '--build', '.', '--config', 'Release'], cwd=self.build_temp) print() # Add an empty line for cleaner output diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index acc656de..00deb14c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,11 +5,12 @@ if(UNIX) else() # Linux add_definitions(-DLINUX) endif() + add_compile_options(-fPIC) else() # Windows - add_definitions(-DWIN32) + set(WINDOWS_EXPORT_ALL_SYMBOLS ON) + add_definitions(-DWIN32 -D_WINDOWS -D_USRDLL -D_CRT_SECURE_NO_WARNINGS -DNON_UNIX_STDIO -D__VC__) endif() -add_compile_options(-fPIC) message(STATUS "Compiler is: ${CMAKE_C_COMPILER} | ${CMAKE_CXX_COMPILER}") @@ -28,4 +29,4 @@ add_subdirectory(lib) if(BUILD_CLIENTS) add_subdirectory(clients) -endif() \ No newline at end of file +endif() diff --git a/src/clients/python/CMakeLists.txt b/src/clients/python/CMakeLists.txt index adfc0438..11fbacda 100644 --- a/src/clients/python/CMakeLists.txt +++ b/src/clients/python/CMakeLists.txt @@ -1,51 +1,43 @@ -set(srw_clients_python_source_files - srwlpy.cpp -) - -add_library(srwlpy SHARED ${srw_clients_python_source_files}) - # for testing we will need the python interpreter find_package(PythonInterp REQUIRED) # we require python development headers find_package(PythonLibs ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED) -target_link_libraries(srwlpy srw m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) -target_include_directories(srwlpy PRIVATE - ${PYTHON_INCLUDE_DIRS} +set(srw_clients_python_source_files + srwlpy.cpp ) -target_include_directories(srwlpy PUBLIC - $ -) +add_library(srwlpy SHARED ${srw_clients_python_source_files}) + +target_include_directories(srwlpy PUBLIC ${PYTHON_INCLUDE_DIRS}) + +target_include_directories(srwlpy PUBLIC $) # prevent cmake from creating a "lib" prefix -set_target_properties(srwlpy - PROPERTIES - PREFIX "" -) +set_target_properties(srwlpy PROPERTIES PREFIX "") -if(WIN32) - # python will not import dll but expects pyd - set_target_properties(srwlpy - PROPERTIES - SUFFIX ".pyd" - ) -endif() -if(UNIX) - # python will not import dll but expects pyd - set_target_properties(srwlpy - PROPERTIES - SUFFIX ".so" - ) +if (UNIX) + # Math library is only needed by unix. When using Windows, VS does it for you. + target_link_libraries(srwlpy m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB} srw) + + set_target_properties(srwlpy PROPERTIES SUFFIX ".so") + + # The -shared flag is only valid for UNIX systems. + set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-shared") endif() + if(APPLE) # We need the undefined dynamic_lookup to overcome issues with a statically linked # python. More details here: https://gitlab.kitware.com/vtk/vtk/-/issues/17214 set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-undefined dynamic_lookup -shared") -else() - set_target_properties(srwlpy PROPERTIES LINK_FLAGS "-shared") endif() -install(TARGETS srwlpy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +if(WIN32) + target_link_libraries(srwlpy srw ${PYTHON_LIBRARIES}) + set_target_properties(srwlpy PROPERTIES SUFFIX ".pyd") +endif() + + +install(TARGETS srwlpy LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) \ No newline at end of file diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 669a42c4..2c17a1c6 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -15,13 +15,19 @@ add_library(srw STATIC # Add definitions needed to build SRW -target_compile_definitions(srw PRIVATE ${SRW_DEFINITIONS}) +target_compile_definitions(srw PUBLIC ${SRW_DEFINITIONS}) + +# Libraries in which SRW lib depends +target_link_libraries(srw core ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) + +if (UNIX) + # Math library is only needed by unix. When using Windows, VS does it for you. + target_link_libraries(srw m) +endif() if (USE_OPENMP) - target_link_libraries(srw PRIVATE core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB} OpenMP::OpenMP_CXX) + target_link_libraries(srw OpenMP::OpenMP_CXX) target_include_directories(srw PUBLIC ${OpenMP_CXX_INCLUDE_DIRS}) -else() - target_link_libraries(srw PRIVATE core m ${FFTW_DOUBLE_LIB} ${FFTW_FLOAT_LIB}) endif() target_include_directories(srw PUBLIC From 16ad10a6c421991f5ffc4fd2c217e9f6b0fc6f02 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Wed, 13 Jan 2021 14:09:22 -0800 Subject: [PATCH 19/21] FIX: Change FFTW build procedure so we can have Windows build with OpenMP. --- ext_lib/fftw/CMakeLists.txt | 138 +++++++++++++++++++++++------------ ext_lib/fftw3/CMakeLists.txt | 8 +- 2 files changed, 94 insertions(+), 52 deletions(-) diff --git a/ext_lib/fftw/CMakeLists.txt b/ext_lib/fftw/CMakeLists.txt index 625bd14c..37fbbd8e 100644 --- a/ext_lib/fftw/CMakeLists.txt +++ b/ext_lib/fftw/CMakeLists.txt @@ -1,63 +1,105 @@ find_package(FFTW2 QUIET COMPONENTS FLOAT_LIB) if(FFTW2_FOUND) - message(STATUS "Found FFTW2F: ${FFTW_FLOAT_LIB}") + message(STATUS "Found FFTW2F: ${FFTW_FLOAT_LIB}") - set( - FFTW_DOUBLE_LIB ${FFTW_DOUBLE_LIB} - CACHE PATH "Path to FFTW" - FORCE - ) + set( + FFTW_DOUBLE_LIB ${FFTW_DOUBLE_LIB} + CACHE PATH "Path to FFTW" + FORCE + ) else() - message(STATUS "Suitable FFTW could not be located. Downloading and building!") - - include(ExternalProject) - ExternalProject_Add(fftw_external - URL - http://www.fftw.org/fftw-2.1.5.tar.gz - URL_HASH - MD5=8d16a84f3ca02a785ef9eb36249ba433 - CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} - PREFIX ${CMAKE_CURRENT_BINARY_DIR} - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - # This cp line is important. FFTW 2 must be build inplace otherwise - # the make part will generate invalid library... - COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/src/fftw_external/. . - COMMAND ./configure --enable-float --with-pic - COMMAND sed -i.bak -e "s/^CFLAGS = /CFLAGS = -fPIC /" Makefile - COMMAND make -j8 - COMMAND mkdir -p ${STAGED_INSTALL_PREFIX}/lib - COMMAND cp fftw/.libs/libfftw.a ${STAGED_INSTALL_PREFIX}/lib - INSTALL_COMMAND "" - ) + message(STATUS "Suitable FFTW could not be located. Downloading and building!") + + include(ExternalProject) + + if(UNIX) + + ExternalProject_Add(fftw_external + URL + http://www.fftw.org/fftw-2.1.5.tar.gz + URL_HASH + MD5=8d16a84f3ca02a785ef9eb36249ba433 + CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + PREFIX ${CMAKE_CURRENT_BINARY_DIR} + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + # This cp line is important. FFTW 2 must be build inplace otherwise + # the make part will generate invalid library... + COMMAND cp -r ${CMAKE_CURRENT_BINARY_DIR}/src/fftw_external/. . + COMMAND ./configure --enable-float --with-pic + COMMAND sed -i.bak -e "s/^CFLAGS = /CFLAGS = -fPIC /" Makefile + COMMAND make -j8 + COMMAND mkdir -p ${STAGED_INSTALL_PREFIX}/lib + COMMAND cp fftw/.libs/libfftw.a ${STAGED_INSTALL_PREFIX}/lib + INSTALL_COMMAND "" + ) + + include(GNUInstallDirs) + + set( + FFTW_ROOT ${STAGED_INSTALL_PREFIX} + CACHE PATH "Path to internally built FFTWConfig.cmake" + FORCE + ) + + set( + FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw.a + CACHE PATH "Path to FFTW" + FORCE + ) + + set( + FFTW_FLOAT_LIB + CACHE PATH "Path to FFTWF" + FORCE + ) + - include(GNUInstallDirs) + # Libraries + add_library(fftw STATIC IMPORTED) + set_property(TARGET fftw PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw.a) + endif() + if(WIN32) + ExternalProject_Add(fftw_external + URL + https://github.com/ochubar/SRW/raw/master/ext_lib/fftw64_f.lib + URL_HASH + MD5=3e34fe1af702ba2af176e83a39021250 + DOWNLOAD_NAME fftwf.lib + DOWNLOAD_DIR ${STAGED_INSTALL_PREFIX}/lib + DOWNLOAD_NO_EXTRACT true + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + ) - set( - FFTW_ROOT ${STAGED_INSTALL_PREFIX} - CACHE PATH "Path to internally built FFTWConfig.cmake" - FORCE - ) + include(GNUInstallDirs) - set( - FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/libfftw.a - CACHE PATH "Path to FFTW" - FORCE - ) + set( + FFTW_ROOT ${STAGED_INSTALL_PREFIX} + CACHE PATH "Path to internally built FFTWConfig.cmake" + FORCE + ) - set( - FFTW_FLOAT_LIB - CACHE PATH "Path to FFTWF" - FORCE - ) + set( + FFTW_DOUBLE_LIB ${STAGED_INSTALL_PREFIX}/lib/fftwf.lib + CACHE PATH "Path to FFTW" + FORCE + ) + set( + FFTW_FLOAT_LIB + CACHE PATH "Path to FFTWF" + FORCE + ) - # Libraries - add_library(fftw STATIC IMPORTED) - set_property(TARGET fftw PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw.a) - add_dependencies(fftw fftw_external) + # Libraries + add_library(fftw STATIC IMPORTED) + set_property(TARGET fftw PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/fftwf.lib) + endif() + add_dependencies(fftw fftw_external) endif() diff --git a/ext_lib/fftw3/CMakeLists.txt b/ext_lib/fftw3/CMakeLists.txt index 62555176..930b501c 100644 --- a/ext_lib/fftw3/CMakeLists.txt +++ b/ext_lib/fftw3/CMakeLists.txt @@ -17,10 +17,12 @@ if(FFTW_FOUND) ) else() + message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") + include(ExternalProject) + if(UNIX) - message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") - include(ExternalProject) + ExternalProject_Add(fftw3_external URL http://www.fftw.org/fftw-3.3.8.tar.gz @@ -67,8 +69,6 @@ else() set_property(TARGET fftw3f PROPERTY IMPORTED_LOCATION ${STAGED_INSTALL_PREFIX}/lib/libfftw3f.a) endif() if(WIN32) - message(STATUS "Suitable FFTW3 could not be located. Downloading and building!") - include(ExternalProject) ExternalProject_Add(fftw3_external URL http://www.fftw.org/fftw-3.3.8.tar.gz From ba898efb8432d4ec1601fe1b47e3378dbc47133e Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Wed, 13 Jan 2021 17:44:39 -0800 Subject: [PATCH 20/21] DOC: Add documentation on install procedure. --- docs/source/installation.rst | 125 ++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 9 deletions(-) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index e4292179..c1b9d0d4 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -2,30 +2,137 @@ Installation ============ -SRW package consists of a C++ library and client libraries for: +SRW uses leverages the OS portability features of CMake for its build system. +This package consists of a C++ library and client libraries for: - C - Python - Igor PRO +------------ +Dependencies +------------ + +SRW depends on the following external dependencies: + +- CMake >= 3.12 +- C/C++ compiler +- FFTW library (3.x for regular build or 2.x if selecting OpenMP) + +Note: The proper FFTW library will be built as part of the C++ library if not found on the system. + +Optional Dependencies +===================== + +- Python 2.7 or 3.6+ (required for Python client) +- Igor Pro (required for Igor Pro client) +- Igor XOP (required for Igor Pro client) + +--------------- +Build Procedure +--------------- + +As mentioned above, SRW relies on CMake for generation of the files necessary for +building the main SRW and client libraries. + +For users looking for the Python client, the procedure is very straightforward +and does not require source build. Please find the instructions below. + +The Source Build is only recommended for users that need the main SRW library to +link with other code or the C and Igor client libraries. + +Source Build +============ + +Before diving on the details for the source build of SRW library it is important +to first look into the options available via CMake to configure the build and install +of the package. + +CMake Options +^^^^^^^^^^^^^ + +Here are the cmake options along with their usage and description for SRW library. + +====================== ====== =============================================== ========================================================== +Option Type Usage Description +====================== ====== =============================================== ========================================================== +-DUSE_OPENMP (bool) -DUSE_OPENMP= Whether or not to build OpenMP capable library +-DBUILD_CLIENTS (bool) -DBUILD_CLIENTS= Whether or not to build `ALL` client libraries +-DBUILD_CLIENT_C (bool) -DBUILD_CLIENT_C= Whether or not to build the C client library +-DBUILD_CLIENT_PYTHON (bool) -DBUILD_CLIENT_PYTHON= Whether or not to build the Python client library +-DCMAKE_INSTALL_PREFIX (str) -DCMAKE_INSTALL_PREFIX=/home/user/software/SRW The path in which to install the build artifacts +====================== ====== =============================================== ========================================================== + + Linux/macOS Instructions ^^^^^^^^^^^^^^^^^^^^^^^^ -From the SRW root folder run:: +When building cmake-based projects, it is common practice to do so in a folder other than the project root directory. - $ make all +As a way to demonstrate how to build and install the SRW library we will simulate a case in which an user wants to +build and install the SRW library (with OpenMP) along with the C client only and have it installed at a specific folder under its home directory. -This command will build the needed dependencies, the main SRW library and also the Python library to be used. +Here are the steps:: -To build SRW with OpenMP support use:: + $ cd SRW # This is the folder in which you have the SRW code + $ mkdir build + $ cd build + $ cmake .. -DUSE_OPENMP=ON -DBUILD_CLIENT_C=ON -DCMAKE_INSTALL_PREFIX=/home/user/my_install_folder/ + $ make + $ make install - $ MODE=omp make all +Windows +^^^^^^^ +When building cmake-based projects, it is common practice to do so in a folder other than the project root directory. -After this step is concluded, you can use the Python library by adding the `python` folder to your `PYTHONPATH` variable -or install the `srwpy` package at your Python distribution via the `setup.py` file. +As a way to demonstrate how to build and install the SRW library we will simulate a case in which an user wants to +build and install the SRW library (with OpenMP) along with the C client only and have it installed at a specific folder under its C: drive. + +Here are the steps:: + + $ cd SRW # This is the folder in which you have the SRW code + $ mkdir build + $ cd build + $ cmake .. -DUSE_OPENMP=ON -DBUILD_CLIENT_C=ON -DCMAKE_INSTALL_PREFIX=C:\my_install_folder + $ cmake --build . --config Release --target install + + +Python Client +============= + +When installing the Python client, it will automatically take care of building +the SRW library as part of the process. + +Linux/macOS Instructions +^^^^^^^^^^^^^^^^^^^^^^^^ + +In order to install the regular SRW (non-OpenMP) do:: + + $ cd python + $ python setup.py install + +In order to install the OpenMP capable SRW do:: + + $ cd python + $ MODE=omp python setup.py install Windows ^^^^^^^ -TODO +In order to install the regular SRW (non-OpenMP) do:: + + $ cd python + $ python setup.py install + +In order to install the OpenMP capable SRW do:: + + $ cd python + $ set MODE=omp + $ python setup.py install + + +Igor Pro Client +=============== + +TODO \ No newline at end of file From 34079b54e537c9a44e44216c7cdeb6608f547c86 Mon Sep 17 00:00:00 2001 From: Hugo Slepicka Date: Wed, 13 Jan 2021 18:27:05 -0800 Subject: [PATCH 21/21] FIX: Remove -DBUILD_CLIENTS option which was unnecessary and update documentation to reflect changes. --- CMakeLists.txt | 3 --- docs/source/installation.rst | 6 ++++-- python/setup.py | 1 - src/CMakeLists.txt | 4 +--- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c1601a6..84e0bce6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,9 +26,6 @@ set(CMAKE_BUILD_TYPE Release) # Option for OpenMP build, OFF by default. option(USE_OPENMP "Activate OpenMP build" OFF) -# Option for Client libraries to be built or not - See src/clients/CMakeLists.txt -option(BUILD_CLIENTS "Activate Client libraries build" OFF) - # Option for C client library to be built or not - See src/clients/CMakeLists.txt option(BUILD_CLIENT_C "Activate C Client library build" OFF) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index c1b9d0d4..43e990d8 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -57,7 +57,6 @@ Here are the cmake options along with their usage and description for SRW librar Option Type Usage Description ====================== ====== =============================================== ========================================================== -DUSE_OPENMP (bool) -DUSE_OPENMP= Whether or not to build OpenMP capable library --DBUILD_CLIENTS (bool) -DBUILD_CLIENTS= Whether or not to build `ALL` client libraries -DBUILD_CLIENT_C (bool) -DBUILD_CLIENT_C= Whether or not to build the C client library -DBUILD_CLIENT_PYTHON (bool) -DBUILD_CLIENT_PYTHON= Whether or not to build the Python client library -DCMAKE_INSTALL_PREFIX (str) -DCMAKE_INSTALL_PREFIX=/home/user/software/SRW The path in which to install the build artifacts @@ -94,10 +93,13 @@ Here are the steps:: $ cd SRW # This is the folder in which you have the SRW code $ mkdir build $ cd build - $ cmake .. -DUSE_OPENMP=ON -DBUILD_CLIENT_C=ON -DCMAKE_INSTALL_PREFIX=C:\my_install_folder + $ cmake .. -GNMake Makefiles -DUSE_OPENMP=ON -DBUILD_CLIENT_C=ON -DCMAKE_INSTALL_PREFIX=C:\my_install_folder $ cmake --build . --config Release --target install +Note: For Windows it is necessary to specify the *-G* option to select a build system that does not support multi-configuration builds otherwise it will install +the artifacts in a folder called Release or Debug depending on the *--config* selected. + Python Client ============= diff --git a/python/setup.py b/python/setup.py index 417a234c..1c8669c9 100644 --- a/python/setup.py +++ b/python/setup.py @@ -37,7 +37,6 @@ def build_extension(self, ext): os.path.dirname(self.get_ext_fullpath(ext.name))) extdir = os.path.join(extdir, ext.package_name) cmake_args = [ - '-DBUILD_CLIENTS=ON', '-DBUILD_CLIENT_PYTHON=ON', '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, '-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=' + extdir, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00deb14c..3e0c6b28 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,6 +27,4 @@ add_subdirectory(ext) add_subdirectory(core) add_subdirectory(lib) -if(BUILD_CLIENTS) - add_subdirectory(clients) -endif() +add_subdirectory(clients) \ No newline at end of file