C++QED  v2 Milestone 10
a framework for simulating open quantum dynamics
CMakeLists.cmake
1 # Copyright Raimar Sandner 2012–2014. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt)
2 
3 #! \addtogroup Main
4 #! @{
5 
6 #! \file
7 #! \brief Top level %CMake file controlling monolithic builds.
8 #!
9 #! In monolithic builds, the paths to the subprojects (`CPPQEDcore`, `CPPQEDelements`, `CPPQEDscripts`, `cpypyqed`)
10 #! are known. All these components are built with calls to `add_subdirectory` from within this file. The subprojects
11 #! are built just as if they were standalone projects (with very few exceptions where the variable `CPPQED_MONOLITHIC`
12 #! is queried and things are handled differently if it is defined). `CPPQEDcore` and `CPPQEDelements`
13 #! export their relevant targets and other subprojects import them, just as for standalone projects. However, this
14 #! file sets the variables `CPPQED_DIR` and `CPPQEDelements_DIR`
15 #! (c.f. \ref cmake_find_components "how CMake finds components") to the build directories of this monolithic build,
16 #! so that the right subprojects are found even if C++QED is installed or other build directories are registered.
17 #!
18 #! This CMakeLists file has the following structure:
19 
20 #! @}
21 
22 cmake_minimum_required (VERSION 2.8.9)
23 project(cppqed)
24 
25 enable_testing()
26 
27 include(GNUInstallDirs)
28 
29 set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CPPQEDcore/cmake/Modules" "${CMAKE_SOURCE_DIR}/cpypyqed/cmake/Modules")
30 
31 #! \name Project variables
32 #! These variables are used in the subprojects.
33 #! @{
34 
35 #! \brief Other subprojects use this variable to determine if this is a monolithic build
36 set(CPPQED_MONOLITHIC 1)
37 
38 set(cppqed_DOC_DIR ${CMAKE_BINARY_DIR}/doc/cppqed)
39 set(core_DOC_DIR ${CMAKE_BINARY_DIR}/doc/core)
40 set(core_DOXYGEN_TAG ${core_DOC_DIR}/core.tag)
41 set(elements_DOC_DIR ${CMAKE_BINARY_DIR}/doc/elements)
42 set(elements_DOXYGEN_TAG ${elements_DOC_DIR}/elements.tag)
43 set(cpypyqed_DOC_DIR ${CMAKE_BINARY_DIR}/doc/cpypyqed)
44 
45 #! @}
46 
47 #! \file
48 #! <!--#########################################################-->
49 #! ### Compilation of dependencies
50 #! <!--#########################################################-->
51 #!
52 #! This is a convenience feature to download and compile some selected
53 #! dependencies automatically. It uses %CMake's
54 #! [ExternalProject](http://www.cmake.org/cmake/help/v2.8.12/cmake.html#module:ExternalProject).
55 #!
56 #! We use a trick to install the bundled libraries. If the bundled version of a library is used,
57 #! we link it privately (\ref CMake::PRIVATE_LIBS instead of \ref CMake::PUBLIC_LIBS). Then
58 #! we add the library manually to `CPPQED_LIBRARIES` in CPPQEDConfig.cmake.in, with the correct
59 #! location for the build tree and installed tree, respectively.
60 
61 #! If this option is set, %CMake downloads and compiles the blitz++ dependency automatically.
62 option(BUNDLED_BLITZ "Download and compile blitz++ automatically" Off)
63 
64 if(BUNDLED_BLITZ)
65  include(ExternalProject)
66 
67  find_package(Boost QUIET COMPONENTS serialization)
68  if(Boost_SERIALIZATION_FOUND)
69  set(BLITZ_CONFIG_OPTIONS "${BLITZ_CONFIG_OPTIONS} --enable-serialization ")
70  set(blitz_SERIALIZATION_FOUND On)
71  endif()
72 
73  string(REGEX REPLACE "/include" "" local_boost_root ${Boost_INCLUDE_DIR})
74 
75  if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) # 64bit system
76  set(BLITZ_CONFIG_OPTIONS "${BLITZ_CONFIG_OPTIONS} --enable-64bit ")
77  else( CMAKE_SIZEOF_VOID_P EQUAL 8 ) # 32bit system
78  set(BLITZ_CONFIG_OPTIONS "${BLITZ_CONFIG_OPTIONS} --enable-simd-width=8 ")
79  endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
80 
81  find_program(autoreconf autoreconf)
82  if(NOT autoreconf)
83  message(FATAL_ERROR "Program autoreconf not found, needed to compile blitz.")
84  endif()
85  get_filename_component(AUTOTOOLS_PATH ${autoreconf} DIRECTORY)
86 
87  if(XCODE)
88  set(AUTORECONF_NO_OUTPUT "&>/dev/null")
89  endif()
90  configure_file(misc/blitz-make.sh.in ${PROJECT_BINARY_DIR}/blitz-make.sh @ONLY)
91 
92  ExternalProject_Add(
93  cppqed-blitz
94  HG_REPOSITORY http://hg.code.sf.net/p/cppqed/blitz
95  UPDATE_COMMAND ""
96  PATCH_COMMAND patch --dry-run -N -p1 -d <SOURCE_DIR> -i ${CMAKE_SOURCE_DIR}/misc/blitz_rename_library.patch | grep "previously applied" || patch -p1 -d <SOURCE_DIR> -i ${CMAKE_SOURCE_DIR}/misc/blitz_rename_library.patch
97  COMMAND patch --dry-run -N -p1 -d <SOURCE_DIR> -i ${CMAKE_SOURCE_DIR}/misc/blitz_python26.patch | grep "previously applied" || patch -p1 -d <SOURCE_DIR> -i ${CMAKE_SOURCE_DIR}/misc/blitz_python26.patch
98  CONFIGURE_COMMAND ${PROJECT_BINARY_DIR}/blitz-make.sh <SOURCE_DIR> <INSTALL_DIR>
99  BUILD_COMMAND make lib
100  )
101  ExternalProject_Get_Property(cppqed-blitz install_dir)
102  set(blitz_INCLUDE_DIRS ${install_dir}/include)
103  set(blitz_LIBRARIES ${install_dir}/lib/libblitzcppqed${CMAKE_SHARED_LIBRARY_SUFFIX})
104  set(BUNDLED_BLITZ_INSTALLED_LIBRARY ${CMAKE_INSTALL_FULL_LIBDIR}/libblitzcppqed${CMAKE_SHARED_LIBRARY_SUFFIX})
105  set(blitz_FOUND 1)
106 endif()
107 
108 #! If this option is set, %CMake downloads and compiles the optional FLENS dependency automatically.
109 option(BUNDLED_FLENS "Download and compile FLENS automatically" Off)
110 
111 if(BUNDLED_FLENS)
112  include(ExternalProject)
113  ExternalProject_Add(
114  flens
115  GIT_REPOSITORY git://github.com/michael-lehn/FLENS.git
116  # Bug in HEAD
117  GIT_TAG "846b5a3"
118  UPDATE_COMMAND ""
119  CONFIGURE_COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> ../flens/
120  BUILD_COMMAND
121  INSTALL_COMMAND make install
122  )
123  ExternalProject_Get_Property(flens install_dir)
124  set(flens_INCLUDE_DIRS ${install_dir}/include)
125  set(flens_FOUND 1)
126 endif()
127 
128 #! \file
129 #! <!--#########################################################-->
130 #! ### Compilation of the components
131 #! <!--#########################################################-->
132 #!
133 #! Compile the components core, elements, scripts (optional) and cpypyqed (optional)
134 #! by adding their sub-directories.
135 
136 add_subdirectory(CPPQEDcore)
137 set(CPPQED_DIR ${core_BINARY_DIR})
138 add_subdirectory(CPPQEDelements)
139 set(CPPQEDelements_DIR ${elements_BINARY_DIR})
140 
141 #! \brief Install directory of the Doxygen documentation.
142 #!
143 #! Note that doxygen documentation can only be built and installed in monolithic builds.
144 set(CPPQED_DOC_DIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/cppqed-doc-${CPPQED_ID}")
145 
146 #! \name Project options
147 #! @{
148 
149 #! This %CMake option determines if the Python modules should be compiled.
150 option(COMPILE_CPYPYQED "Compile Python wrapper and Python I/O module" On)
151 find_package(Boost QUIET COMPONENTS python)
152 find_package(PythonInterp 2 QUIET)
153 if(${PYTHON_VERSION_STRING} VERSION_LESS 2.6)
154  message(WARNING "Python2 >=2.6 needed, disabling cpypyqed and testsuite.")
155  set(PYTHONINTERP_FOUND 0)
156 else()
157  find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT QUIET)
158 endif()
159 find_package(Numpy QUIET)
160 
161 # Canopy workaround: the python interpreter is found, but not the libs and include dirs
162 if(PYTHONINTERP_FOUND AND NOT PYTHONLIBS_FOUND)
163  execute_process(COMMAND "${PYTHON_EXECUTABLE}-config" "--includes"
164  OUTPUT_VARIABLE _PYTHON_CONFIG_INCLUDES
165  RESULT_VARIABLE _PYTHON_CONFIG_SUCCESS)
166  if(_PYTHON_CONFIG_SUCCESS MATCHES 0)
167  string(REGEX REPLACE "-I(.*) .*" "\\1" PYTHON_INCLUDE_DIR ${_PYTHON_CONFIG_INCLUDES})
168  get_filename_component(_PYTHON_BASE ${PYTHON_INCLUDE_DIR} DIRECTORY)
169  get_filename_component(_PYTHON_BASE ${_PYTHON_BASE} DIRECTORY)
170  set(PYTHON_LIBRARY ${_PYTHON_BASE}/lib/libpython${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}${CMAKE_SHARED_LIBRARY_SUFFIX})
171  message(STATUS "Trying to find python library at ${PYTHON_LIBRARY}")
172  message(STATUS "Trying to find python includes at ${PYTHON_INCLUDE_DIR}")
173  find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT QUIET)
174  endif()
175 endif()
176 
177 
178 # For some reason kdevelop does not recognize PYTHONLIBS_FOUND, use PYTHON_INCLUDE_DIRS instead
179 if(Boost_PYTHON_FOUND AND PYTHONINTERP_FOUND AND PYTHON_INCLUDE_DIRS AND NUMPY_FOUND AND COMPILE_CPYPYQED)
180  set(ENABLE_CPYPYQED 1)
181 endif()
182 add_subdirectory(cpypyqed)
183 
184 
185 #! \brief This %CMake option determines if the scripts should be compiled as part
186 #! of the monolithic build.
187 option(COMPILE_SCRIPTS "Compile the example scripts" On)
188 
189 #! \brief This %CMake configuration variable lets users exclude scripts from the ALL target. These
190 #! scripts can still be compiled by directly calling their target.
191 set(CPPQED_EXCLUDE_SCRIPTS "" CACHE STRING "Exclude from the ALL target")
192 #! @}
193 if(COMPILE_SCRIPTS)
194  add_subdirectory(CPPQEDscripts)
195 endif()
196 
197 add_subdirectory(Testing)
198 
199 # The EXCLUDE_FROM_ALL target makes Xcode scip the subdirectory entirely
200 if(XCODE)
201  add_subdirectory(CustomElementsExample)
202  set(CPPQEDelements_custom_example_DIR ${elements_custom_example_BINARY_DIR})
203  add_subdirectory(CustomScriptsExample)
204 else()
205  add_subdirectory(CustomElementsExample EXCLUDE_FROM_ALL)
206  set(CPPQEDelements_custom_example_DIR ${elements_custom_example_BINARY_DIR})
207  add_subdirectory(CustomScriptsExample EXCLUDE_FROM_ALL)
208 endif()
209 
210 #! \file
211 #! <!--#########################################################-->
212 #! ### Installation of dependencies
213 #! <!--#########################################################-->
214 #!
215 #! If blitz and flens are compiled as external projects, install them as well. Libraries
216 #! and header files are installed into the same locations as CPPQEDcore, this way it is
217 #! ensured they are found.
218 
219 set(BUNDLED_HEADERS "${CMAKE_INSTALL_INCLUDEDIR}/${CPPQED_INCLUDE_DIR}/bundled")
220 
221 if(BUNDLED_BLITZ)
222  ExternalProject_Get_Property(cppqed-blitz install_dir)
223  file(GLOB blitz_libs ${install_dir}/lib/*.so*)
224  set(blitz_libs ${install_dir}/lib/libblitzcppqed.so
225  ${install_dir}/lib/libblitzcppqed.so.0
226  ${install_dir}/lib/libblitzcppqed.so.0.0.0)
227  install(FILES ${blitz_libs}
228  PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE
229  DESTINATION ${CMAKE_INSTALL_LIBDIR})
230  install(DIRECTORY ${install_dir}/include/blitz ${install_dir}/include/random
231  DESTINATION ${BUNDLED_HEADERS})
232 endif()
233 
234 if(BUNDLED_FLENS)
235  ExternalProject_Get_Property(flens install_dir)
236  install(DIRECTORY ${install_dir}/include/flens
237  DESTINATION ${BUNDLED_HEADERS})
238 endif()
239 
240 #! \file
241 #! <!--#########################################################-->
242 #! ### Source package
243 #! <!--#########################################################-->
244 #!
245 #! Create source tar ball with CPack for publication on sourceforge.
246 
247 set(CPACK_PACKAGE_VERSION_MAJOR ${CPPQED_VERSION_MAJOR})
248 set(CPACK_PACKAGE_VERSION_MINOR ${CPPQED_VERSION_MINOR})
249 set(CPACK_PACKAGE_VERSION_PATCH ${CPPQED_VERSION_PATCH})
250 
251 set(CPACK_GENERATOR TGZ)
252 
253 set(CPACK_SOURCE_PACKAGE_FILE_NAME "cppqed-${CPPQED_VERSION}" CACHE INTERNAL "tarball basename")
254 set(CPACK_SOURCE_IGNORE_FILES "~$" "/build/" "\\\\.kdev4.*" "\\\\.git.*" ".*orig$")
255 
256 include(CPack)
257 
258 #! \file
259 #! <!--#########################################################-->
260 #! ### Documentation
261 #! <!--#########################################################-->
262 #!
263 #! This section builds the Doxygen documentation (if Doxygen is found) and furthermore
264 #! installs the example projects "CustomElementsExample" and "CustomScriptsExample" to
265 #! the system. The install location is \ref CMake::CPPQED_DOC_DIR "CPPQED_DOC_DIR".
266 #!
267 #! For the Doxygen documentation, the filter [CMakeDoxygenFilter](https://github.com/saschazelzer/CMakeDoxygenFilter),
268 #! is compiled, which allows to document %CMake in Doxygen. The overall C++QED documentation
269 #! is generated with cppqed_documentation(), and a target "doc" for the full documentation is created,
270 #! which depends on all the component documentation targets.
271 
272 include(${core_SOURCE_DIR}/cmake/Modules/CPPQEDUse.cmake)
273 add_executable(CMakeDoxygenFilter doc/CMakeDoxygenFilter.cpp)
274 set_target_properties(CMakeDoxygenFilter PROPERTIES COMPILE_FLAGS -DUSE_NAMESPACE=CMake)
275 set(CMakeDoxygenFilter_EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/CMakeDoxygenFilter${CMAKE_EXECUTABLE_SUFFIX}")
276 cppqed_documentation("cppqed_" "${CMAKE_BINARY_DIR}/doc/core/core.tag;${CMAKE_BINARY_DIR}/doc/elements/elements.tag" core_doc elements_doc CMakeDoxygenFilter)
277 if(DOXYGEN_FOUND)
278  add_custom_target(doc)
279  add_dependencies(doc cppqed_doc core_doc elements_doc cpypyqed_doc)
280  configure_file(doc/index.html ${CMAKE_BINARY_DIR}/doc COPYONLY)
281 endif()
282 
283 install(DIRECTORY CustomElementsExample CustomScriptsExample
284  DESTINATION ${CPPQED_DOC_DIR}
285  PATTERN .git* EXCLUDE
286  PATTERN .bzr EXCLUDE
287  PATTERN *.kdev* EXCLUDE
288  PATTERN build* EXCLUDE
289 )
290 
291 #! \file
292 #! <!--#########################################################-->
293 #! ### Debian build
294 #! <!--#########################################################-->
295 #!
296 #! This adds the sub-directory "debianbuild" if it exists. If not this section is silently ignored.
297 #! The directory "debianbuild" is not part of the C++QED project. One can put a special
298 #! [repository](https://ge-c705.uibk.ac.at/cppqed/debian) here, which will then generate debian
299 #! directories for building source packages. This guarantees that debian packages have the right
300 #! version numbers and soversion in their package names, and also helps to maintain packages for different
301 #! distributions without code duplication.
302 
303 if(EXISTS ${PROJECT_SOURCE_DIR}/debianbuild)
304  add_subdirectory(debianbuild)
305 endif()
306 
307 add_feature_info("cpypyqed" ENABLE_CPYPYQED "Python part of C++QED (wrapper and input/output).")
308 feature_summary( WHAT ALL )