From 4fdc46f7636fc9fc0d2501086215dbf5f5993b46 Mon Sep 17 00:00:00 2001
From: Ole Hansen <ole@jlab.org>
Date: Sun, 15 Jul 2018 19:23:28 -0400
Subject: [PATCH] Experimental CMake support

Requires Podd at commit JeffersonLab/analyzer@aa4c6a8
---
 .gitignore              |   3 +-
 CMakeLists.txt          |  39 +++++++++++++
 README.md               |  49 ++++++++++++++--
 src/CMakeLists.txt      | 125 ++++++++++++++++++++++++++++++++++++++++
 src/hc_compiledata.h.in |  18 ++++++
 5 files changed, 229 insertions(+), 5 deletions(-)
 create mode 100644 CMakeLists.txt
 create mode 100644 src/CMakeLists.txt
 create mode 100644 src/hc_compiledata.h.in

diff --git a/.gitignore b/.gitignore
index a3272f6..06edde6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,5 +57,6 @@ examples/HScaler.txt
 examples/raw
 examples/cache
 
-# Working directory
+# Working directories
 work
+build*
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..b875959
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,39 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(hcana VERSION 0.90 LANGUAGES CXX)
+
+#----------------------------------------------------------------------------
+# Use our modules and utility functions
+set(CMAKE_MODULE_PATH
+  ${PROJECT_SOURCE_DIR}/podd/cmake/Modules
+  ${CMAKE_MODULE_PATH}
+  )
+include(PoddCMakeEnv)
+
+#----------------------------------------------------------------------------
+# Install in GNU-style directory layout
+include(GNUInstallDirs)
+set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME_LC})
+
+#----------------------------------------------------------------------------
+# Find ROOT (using Podd's FindROOT.cmake)
+find_package(ROOT 5.10 MODULE REQUIRED)
+
+#----------------------------------------------------------------------------
+# Set up the compiler flags
+set_compiler_flags("${ROOT_CXX_FLAGS}")
+set_diagnostic_flags(WALL WEXTRA)
+report_build_info()
+
+#----------------------------------------------------------------------------
+# Directories in which we build things
+add_subdirectory(podd)
+add_subdirectory(src)
+
+#----------------------------------------------------------------------------
+# Install and export targets defined in the subdirectories
+install(EXPORT ${PROJECT_NAME_LC}-exports
+ FILE ${PROJECT_NAME}Targets.cmake
+ NAMESPACE ${PROJECT_NAME}::
+ DESTINATION ${INSTALL_CONFIGDIR}
+ )
diff --git a/README.md b/README.md
index b39b884..48d0a94 100644
--- a/README.md
+++ b/README.md
@@ -31,11 +31,11 @@ Before compiling, type
 `source setup.sh` or `source setup.csh`
 depending on whether your shell is bash or csh.
 
-### Compiling with make
-    make
-
 ### Compiling with scons
-    scons
+
+```
+scons
+```
 
 ### Additional SCons features 
 To do the equivalent of "make clean", do
@@ -47,6 +47,47 @@ To compile the standalone codes the are part of podd, do
 To run cppcheck (if installed) on the Hall C src diretory, do
 `scons cppcheck=1`
 
+### Compiling with CMake (experimental)
+
+Do the usual CMake setup
+
+```
+mkdir build
+cd build
+cmake -DCMAKE_INSTALL_PREFIX=$HOME/local/hcana ..
+make -jN install
+```
+
+Here `$HOME/local/hcana` is an example installation destination;
+modify as appropriate. You will need to add the `bin` and `lib[64]` sub-directories
+under the installation prefix to your environment:
+
+```
+export PATH=$HOME/local/hcana/bin:$PATH
+export LD_LIBRARY_PATH=$HOME/local/hcana/lib64:$LD_LIBRARY_PATH
+```
+
+On macOS, the library directory is usually simply `lib` instead of `lib64`.
+
+CMake does not yet support the SCons features "standalone" and "cppcheck".
+
+The default CMake build type is "RelWithDebInfo", i.e. debug symbols are
+included in the binaries, but the code is optimized, which may cause the
+debugger to act in a confusing way on occasion. To build a
+non-optimized debug version, run CMake as follows:
+```
+mkdir build
+cd build
+cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=$HOME/local/hcana-dbg ..
+make -jN install
+```
+
+### Compiling with make (deprecated)
+
+```
+make [-jN]
+```
+
 Running
 -------
 Basic instructions on how to run hcana are in the
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..a37c284
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,125 @@
+cmake_minimum_required(VERSION 3.5)
+
+#----------------------------------------------------------------------------
+# Names of the main items we build here
+set(LIBNAME HallC)
+set(EXENAME hcana)
+
+#----------------------------------------------------------------------------
+# Sources and headers
+file(GLOB src "*.cxx")
+file(GLOB allheaders "*.h")
+list(REMOVE_ITEM allheaders
+  "${CMAKE_CURRENT_SOURCE_DIR}/${LIBNAME}_LinkDef.h"
+  )
+set(headers "${allheaders}")
+list(REMOVE_ITEM headers
+  "${CMAKE_CURRENT_SOURCE_DIR}/hc_compiledata.h"
+  )
+set(classheaders "${headers}")
+list(REMOVE_ITEM classheaders
+  "${CMAKE_CURRENT_SOURCE_DIR}/THcGlobals.h"
+  )
+
+#----------------------------------------------------------------------------
+# Generate HallC_LinkDef.h
+set(linkdef "${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}_LinkDef.h")
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${LIBNAME}_LinkDef.h_preamble" preamble)
+file(WRITE "${linkdef}" "${preamble}")
+unset(preamble)
+foreach(hdr IN LISTS classheaders)
+  get_filename_component(basename "${hdr}" NAME_WE)
+  if("${basename}" MATCHES "^Scaler" OR "${basename}" STREQUAL "TIBlobModule")
+    file(APPEND ${linkdef} "#pragma link C++ class Decoder::${basename}+;\n")
+  else()
+    file(APPEND ${linkdef} "#pragma link C++ class ${basename}+;\n")
+  endif()
+endforeach()
+file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${LIBNAME}_LinkDef.h_postamble" postamble)
+file(APPEND "${linkdef}" "${postamble}")
+unset(postamble)
+
+#----------------------------------------------------------------------------
+# Generate ha_compiledata.h
+include(PoddCompileInfo)
+configure_file(hc_compiledata.h.in hc_compiledata.h)
+list(APPEND allheaders "${CMAKE_CURRENT_BINARY_DIR}/hc_compiledata.h")
+
+#----------------------------------------------------------------------------
+# libHallC
+add_library(${LIBNAME} SHARED ${src} ${allheaders} ${LIBNAME}Dict.cxx)
+add_library(${PROJECT_NAME}::${LIBNAME} ALIAS ${LIBNAME})
+
+target_include_directories(${LIBNAME}
+  PUBLIC
+    $<INSTALL_INTERFACE:include>
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>  # for hc_compiledata.h
+  )
+
+target_compile_options(${LIBNAME}
+  PUBLIC
+    ${${PROJECT_NAME_UC}_CXX_FLAGS_LIST}
+  PRIVATE
+    ${${PROJECT_NAME_UC}_DIAG_FLAGS_LIST}
+  )
+if(WITH_DEBUG)
+  target_compile_definitions(${LIBNAME} PUBLIC WITH_DEBUG)
+endif()
+
+target_link_libraries(${LIBNAME}
+  PUBLIC
+    Podd::HallA
+    Podd::Decode
+  )
+set_target_properties(${LIBNAME} PROPERTIES
+  SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
+  VERSION ${PROJECT_VERSION}
+  EXPORT_NAME ${LIBNAME}
+  )
+
+install(TARGETS ${LIBNAME}
+  EXPORT ${PROJECT_NAME_LC}-exports
+  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+  )
+install(FILES ${allheaders} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+
+#----------------------------------------------------------------------------
+# libHallCDict
+get_target_definitions(${LIBNAME} defines)
+
+root_generate_dictionary(${LIBNAME} ${defines} ${headers}
+  TARGETS ${LIBNAME}
+  LINKDEF ${linkdef}
+  )
+set(PCM_FILE ${CMAKE_CURRENT_BINARY_DIR}/lib${LIBNAME}_rdict.pcm)
+
+add_custom_target(${LIBNAME}_ROOTDICT
+  DEPENDS ${src} ${headers} ${LIBNAME}_LinkDef.h ${LIBNAME}Dict.cxx)
+
+install(FILES ${PCM_FILE} DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+#----------------------------------------------------------------------------
+# hcana executable
+add_executable(${EXENAME} main.C)
+
+target_link_libraries(${EXENAME}
+  PRIVATE
+    ${LIBNAME}
+  )
+target_compile_options(${EXENAME}
+  PUBLIC
+    ${${PROJECT_NAME_UC}_CXX_FLAGS_LIST}
+  PRIVATE
+    ${${PROJECT_NAME_UC}_DIAG_FLAGS_LIST}
+  )
+if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
+  # Linux (at least with g++) requires -fPIC even for main
+  target_compile_options(${EXENAME} PUBLIC -fPIC)
+endif()
+
+install(TARGETS ${EXENAME}
+  DESTINATION ${CMAKE_INSTALL_BINDIR}
+  )
diff --git a/src/hc_compiledata.h.in b/src/hc_compiledata.h.in
new file mode 100644
index 0000000..6fa8016
--- /dev/null
+++ b/src/hc_compiledata.h.in
@@ -0,0 +1,18 @@
+#ifndef HCANA_COMPILEDATA_H
+#define HCANA_COMPILEDATA_H
+
+#define HC_INCLUDEPATH "@CMAKE_INSTALL_FULL_INCLUDEDIR@"
+#define HC_VERSION     "@PROJECT_VERSION@@EXTVERS@"
+#define HC_DATE        "@HCANA_BUILD_DATE@"
+#define HC_DATETIME    "@HCANA_BUILD_DATETIME@"
+#define HC_PLATFORM    "@HCANA_PLATFORM@"
+#define HC_BUILDNODE   "@HCANA_NODE@"
+#define HC_BUILDDIR    "@PROJECT_BINARY_DIR@"
+#define HC_BUILDUSER   "@HCANA_BUILD_USER@"
+#define HC_GITVERS     "@HCANA_GIT_REVISION@"
+#define HC_CXXVERS     "@HCANA_CXX_VERSION@"
+#define HC_ROOTVERS    "@ROOT_CONFIG_VERSION@"
+
+#define HCANA_VERSION_CODE  @HCANA_VERCODE@
+#define HCANA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
-- 
GitLab