From 7535a7dd6769ecc9c95dbc7776cd7a2b21e0874b Mon Sep 17 00:00:00 2001
From: Simon Spannagel <simon.spannagel@cern.ch>
Date: Mon, 6 Nov 2017 12:08:44 +0100
Subject: [PATCH] Rework CMake logic to work on folders

---
 CMakeLists.txt                |  2 +
 cmake/corryvreckan.cmake      | 85 +++++++++++++++++++++++++++++++++++
 src/algorithms/CMakeLists.txt | 63 +++++---------------------
 3 files changed, 99 insertions(+), 51 deletions(-)
 create mode 100644 cmake/corryvreckan.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8f4b98120..a19cf942d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -87,6 +87,8 @@ ENDIF()
 # Prerequisistes for Corryvreckan #
 ###################################
 
+INCLUDE("cmake/corryvreckan.cmake")
+
 # Define the libraries
 SET(CORRYVRECKAN_LIBRARIES "")
 
diff --git a/cmake/corryvreckan.cmake b/cmake/corryvreckan.cmake
new file mode 100644
index 000000000..2c7a8932c
--- /dev/null
+++ b/cmake/corryvreckan.cmake
@@ -0,0 +1,85 @@
+# For every algorithm, build a separate library to be loaded by corryvreckan core
+MACRO(corryvreckan_enable_default val)
+    # Get the name of the algorithm
+    GET_FILENAME_COMPONENT(_corryvreckan_algorithm_dir ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+
+    # Build all algorithms by default if not specified otherwise
+    OPTION(BUILD_${_corryvreckan_algorithm_dir} "Build algorithm in directory ${_corryvreckan_algorithm_dir}?" ${val})
+ENDMACRO()
+
+# Common algorithm definitions
+MACRO(corryvreckan_algorithm name)
+    # Get the name of the algorithm
+    GET_FILENAME_COMPONENT(_corryvreckan_algorithm_dir ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+
+    # Build all algorithms by default if not specified otherwise
+    OPTION(BUILD_${_corryvreckan_algorithm_dir} "Build algorithm in directory ${_corryvreckan_algorithm_dir}?" ON)
+
+    # Quit the file if not building this file or all algorithms
+    IF(NOT (BUILD_${_corryvreckan_algorithm_dir} OR BUILD_ALL_ALGORITHMS))
+        RETURN()
+    ENDIF()
+
+    # Put message
+    MESSAGE( STATUS "Building algorithm: " ${_corryvreckan_algorithm_dir} )
+
+    # Prepend with the algorithm prefix to create the name of the algorithm
+    SET(${name} "CorryvreckanAlgorithm${_corryvreckan_algorithm_dir}")
+
+    # Save the algorithm library for prelinking in the executable (NOTE: see exec folder)
+    SET(CORRYVRECKAN_ALGORITHM_LIBRARIES ${CORRYVRECKAN_ALGORITHM_LIBRARIES} ${${name}} CACHE INTERNAL "Algorithm libraries")
+
+    # Set default algorithm class name
+    SET(_corryvreckan_algorithm_class "${_corryvreckan_algorithm_dir}")
+
+    # Find if alternative algorithm class name is passed or we can use the default
+    SET (extra_macro_args ${ARGN})
+    LIST(LENGTH extra_macro_args num_extra_args)
+    IF (${num_extra_args} GREATER 0)
+        MESSAGE (AUTHOR_WARNING "Provided non-standard algorithm class name! Naming it ${_corryvreckan_algorithm_class} is recommended")
+        LIST(GET extra_macro_args 0 _corryvreckan_algorithm_class)
+    ENDIF ()
+
+    # check if main header file is defined
+    IF(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_corryvreckan_algorithm_class}.h")
+        MESSAGE(FATAL_ERROR "Header file ${_corryvreckan_algorithm_class}.h does not exist, cannot build algorithm! \
+Create the header or provide the alternative class name as first argument")
+    ENDIF()
+
+    # Define the library
+    ADD_LIBRARY(${${name}} SHARED "")
+
+    # Add the current directory as include directory
+    TARGET_INCLUDE_DIRECTORIES(${${name}} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+
+    # Set the special header flags and add the special dynamic implementation file
+    TARGET_COMPILE_DEFINITIONS(${${name}} PRIVATE CORRYVRECKAN_ALGORITHM_NAME=${_corryvreckan_algorithm_class})
+    TARGET_COMPILE_DEFINITIONS(${${name}} PRIVATE CORRYVRECKAN_ALGORITHM_HEADER="${_corryvreckan_algorithm_class}.h")
+
+    TARGET_SOURCES(${${name}} PRIVATE "${PROJECT_SOURCE_DIR}/src/core/algorithm/dynamic_algorithm_impl.cpp")
+    SET_PROPERTY(SOURCE "${PROJECT_SOURCE_DIR}/src/core/algorithm/dynamic_algorithm_impl.cpp" APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${_corryvreckan_algorithm_class}.h")
+ENDMACRO()
+
+# Add sources to the algorithm
+MACRO(corryvreckan_algorithm_sources name)
+    # Get the list of sources
+    SET(_list_var "${ARGN}")
+    LIST(REMOVE_ITEM _list_var ${name})
+
+    # Include directories for dependencies
+    INCLUDE_DIRECTORIES(SYSTEM ${CORRYVRECKAN_DEPS_INCLUDE_DIRS})
+
+    # Add the library
+    TARGET_SOURCES(${name} PRIVATE ${_list_var})
+
+    # Link the standard corryvreckan libraries
+    TARGET_LINK_LIBRARIES(${name} ${CORRYVRECKAN_LIBRARIES} ${CORRYVRECKAN_DEPS_LIBRARIES})
+ENDMACRO()
+
+# Provide default install target for the algorithm
+MACRO(corryvreckan_algorithm_install name)
+    INSTALL(TARGETS ${name}
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION lib
+        ARCHIVE DESTINATION lib)
+ENDMACRO()
diff --git a/src/algorithms/CMakeLists.txt b/src/algorithms/CMakeLists.txt
index ffb0406d7..710fe80cc 100644
--- a/src/algorithms/CMakeLists.txt
+++ b/src/algorithms/CMakeLists.txt
@@ -1,52 +1,13 @@
-MACRO(corryvreckan_algorithm name)
-  # Get the list of sources
-  SET(_list_var "${ARGN}")
-  LIST(REMOVE_ITEM _list_var ${name})
-
-  # Include directories for dependencies
-  INCLUDE_DIRECTORIES(SYSTEM ${CORRYVRECKAN_DEPS_INCLUDE_DIRS})
-
-  # Build all modules by default if not specified otherwise
-  OPTION(BUILD_${name} "Build algorithm ${name}?" ON)
-
-  # Put message
-  MESSAGE(STATUS "Building algorithm: " ${name} )
-
-  # Prepend with the allpix module prefix to create the name of the module
-  SET(LIBNAME "CorryvreckanAlgorithm${name}")
-
-  # Save the module library for prelinking in the executable (NOTE: see exec folder)
-  SET(CORRYVRECKAN_ALGORITHM_LIBRARIES ${CORRYVRECKAN_ALGORITHM_LIBRARIES} ${LIBNAME} CACHE INTERNAL "Algorithm libraries")
-
-  # Define the library
-  ADD_LIBRARY(${LIBNAME} SHARED ${_list_var})
-
-  # Add the current directory as include directory
-  TARGET_INCLUDE_DIRECTORIES(${LIBNAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
-
-  # Set the special header flags and add the special dynamic implementation file
-  TARGET_COMPILE_DEFINITIONS(${LIBNAME} PRIVATE CORRYVRECKAN_ALGORITHM_NAME=${name})
-  TARGET_COMPILE_DEFINITIONS(${LIBNAME} PRIVATE CORRYVRECKAN_ALGORITHM_HEADER="${name}.h")
-
-  TARGET_SOURCES(${LIBNAME} PRIVATE "${PROJECT_SOURCE_DIR}/src/core/algorithm/dynamic_algorithm_impl.cpp")
-  SET_PROPERTY(SOURCE "${PROJECT_SOURCE_DIR}/src/core/algorithm/dynamic_algorithm_impl.cpp" APPEND PROPERTY OBJECT_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${name}.h")
-
-  # Link the standard allpix libraries
-  TARGET_LINK_LIBRARIES(${LIBNAME} ${CORRYVRECKAN_LIBRARIES} ${CORRYVRECKAN_DEPS_LIBRARIES})
-
-  INSTALL(TARGETS ${LIBNAME}
-    RUNTIME DESTINATION bin
-    LIBRARY DESTINATION lib
-  ARCHIVE DESTINATION lib)
-ENDMACRO()
-
-# Include the dependencies
-INCLUDE_DIRECTORIES(SYSTEM ${_DEPS_INCLUDE_DIRS})
-
-# Build all the modules
-FILE(GLOB srcfiles ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
-FOREACH(src ${srcfiles})
-  GET_FILENAME_COMPONENT(name ${src} NAME_WE)
-  # Add the library
-  CORRYVRECKAN_ALGORITHM(${name} ${src})
+# Option to build all algorithms
+OPTION(BUILD_ALL_ALGORITHMS "Build all algorithms?" OFF)
+
+# reset the saved libraries
+SET(CORRYVRECKAN_ALGORITHM_LIBRARIES "" CACHE INTERNAL "Algorithm libraries")
+
+FILE(GLOB subdirs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
+FOREACH(subdir ${subdirs})
+    IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${subdir})
+        # Internal macros check if the module is actually enabled
+        ADD_SUBDIRECTORY(${subdir})
+    ENDIF()
 ENDFOREACH()
-- 
GitLab