CMakeLists.txt 13.5 KB
Newer Older
1
2
3
# CMake version check. 3.14 mimimum available from EPEL.
# 3.15 is required on Windows, but is not available in EPEL yet.
cmake_minimum_required(VERSION 3.14)
4
5

# Define the project name.
6
project(Mantid)
7

8
# Policy settings
9
10
11
if(POLICY CMP0022)
  cmake_policy(SET CMP0022 NEW)
endif()
12

13
14
15
if(POLICY CMP0072)
  cmake_policy(SET CMP0072 OLD)
endif()
16

17
18
19
if(POLICY CMP0074)
  cmake_policy(SET CMP0074 NEW)
endif()
20

21
22
23
24
# System package target is important for the windows builds as it allows us to
# package only the dlls and exes and exclude libs. Defaults to empty for other
# platforms.
set(SYSTEM_PACKAGE_TARGET "")
25

26
# Add the path to our custom 'find' modules
27
28
29
30
31
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/buildconfig/CMake")
# Send libraries to common place, reference in several places so must be at top
# level
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
32

33
option(ENABLE_WORKBENCH "Enable Qt5-based gui & components" ON)
34

35
set(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR}" "Mantid" "ALL" "/")
36

37
38
39
40
# Ensure that if we are running any sanitizers the compiler options are
# known in sub targets
include(Sanitizers)

41
# Quick exit if we only want data targets
42
43
if(DATA_TARGETS_ONLY)
  include(SetupDataTargets)
44
  # System test config files
45
  add_subdirectory(Testing/SystemTests/scripts)
46
47
48
  return()
endif()

49
# Packaging configuration
50
51
set(CPACK_PACKAGE_SUFFIX "unstable"
    CACHE STRING "suffix used to determine the deployment type")
52
53
54
55
56
57
set_property(CACHE CPACK_PACKAGE_SUFFIX
             PROPERTY STRINGS
                      nightly
                      unstable
                      "")
# empty string and release are treated as the same thing
58
59
60
61
62
63
64
if(CPACK_PACKAGE_SUFFIX)
  # Camelcase version of suffix for Windows/Mac
  string(TOUPPER ${CPACK_PACKAGE_SUFFIX} CPACK_PACKAGE_SUFFIX_CAMELCASE)
  string(SUBSTRING ${CPACK_PACKAGE_SUFFIX_CAMELCASE} 0 1 CPACK_PACKAGE_SUFFIX_CAMELCASE)
  string(SUBSTRING ${CPACK_PACKAGE_SUFFIX} 1 -1 _tmp_suffix_remainder)
  string(CONCAT CPACK_PACKAGE_SUFFIX_CAMELCASE ${CPACK_PACKAGE_SUFFIX_CAMELCASE} ${_tmp_suffix_remainder})
endif()
65

66
67
# Set package name here
set(CPACK_PACKAGE_NAME "mantid${CPACK_PACKAGE_SUFFIX}")
68

69
# Bootstrap any dependencies
70
include(Bootstrap)
71

72
# Configure Eigen early
73
include(Eigen)
Hahn, Steven's avatar
Hahn, Steven committed
74
75
include(Span)

Martyn Gigg's avatar
Martyn Gigg committed
76
77
78
if( MSVC )
  include ( MSVCSetup )
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
79
80
  include(DarwinSetup)
endif()
81

82
# Cross-platform setup
83
include(CommonSetup)
84

85
# Find OpenGL
Dan Nixon's avatar
Dan Nixon committed
86
87
88
89
90
91
if(ENABLE_OPENGL)
  find_package(OpenGL REQUIRED)
  # FindOpenGL does not (as of CMake 2.6.4) take notice of the REQUIRED
  if(NOT OPENGL_FOUND)
    message(FATAL_ERROR "OpenGL was not found.")
  endif()
92
endif()
93

94
95
find_package(TBB REQUIRED)

Hahn, Steven's avatar
Hahn, Steven committed
96
97
98
# We probably don't want this to run on every build.
option(COVERALLS "Generate coveralls data" OFF)

99
100
101
if(COVERALLS)
  include(Coveralls)
  coveralls_turn_on_coverage()
Hahn, Steven's avatar
Hahn, Steven committed
102
103
endif()

104
105
106
107
108
109
if(ENABLE_WORKBENCH)
  find_package(Qt5
               COMPONENTS Core
                          Gui
                          Widgets
                          OpenGL
110
                          Test
111
112
113
               REQUIRED)
  if(Qt5_FOUND)
    message(STATUS "Found Qt ${Qt5_VERSION}: ${Qt5_DIR}")
114
  endif()
115
  find_package(QScintillaQt5 REQUIRED)
116
117
118
  find_package(PyQt5 REQUIRED)
  find_package(SIP REQUIRED)
  separate_arguments(PYQT5_SIP_FLAGS)
119
120
endif()

121
# Now add in all the components
Alice Russell's avatar
Alice Russell committed
122

123
# Flag that this is a full build, i.e not framework only
124
125
126
127
set(FULL_PACKAGE_BUILD 1)
# Set the path to the built docs directory here so that it can be used in the
# Kernel project for populating the properties file
set(DOCS_BUILDDIR ${CMAKE_BINARY_DIR}/docs)
128

129
# Framework Build options
130
option(CXXTEST_ADD_PERFORMANCE
Martyn Gigg's avatar
Martyn Gigg committed
131
       "Switch to add performance tests to the list of tests run by ctest?")
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

add_subdirectory(Framework)

include_directories(Framework/Kernel/inc)
include_directories(Framework/HistogramData/inc)
include_directories(Framework/Indexing/inc)
include_directories(Framework/Parallel/inc)
include_directories(Framework/Beamline/inc)
include_directories(Framework/Geometry/inc)
include_directories(Framework/API/inc)
include_directories(Framework/Types/inc)
include_directories(Framework/NexusGeometry/inc)

set(CORE_MANTIDLIBS Kernel HistogramData Indexing Beamline Geometry API Types)

if(UNIX)
  # Experimental feature. Unix only at this point.
149
150
  option(UNITY_BUILD
         "Switch for utilising unity builds. Faster builds for selected components.")
151
endif(UNIX)
152

153
154
155
if(MSVC)
  add_definitions(-DQWT_DLL)
endif()
156

157
158
add_custom_target(AllTests)
add_dependencies(AllTests FrameworkTests)
159

160
if(ENABLE_WORKBENCH)
161
162
  add_custom_target(GUITests)
  add_dependencies(check GUITests)
163
  # Collect all tests together
164
165
  add_dependencies(AllTests GUITests)
  add_subdirectory(qt)
166
endif()
167

168
add_subdirectory(scripts)
169

170
# Docs requirements
171
172
option(ENABLE_DOCS "Enable Building user and developer documentation" ON)
if (ENABLE_DOCS)
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  find_package(Sphinx REQUIRED)
  # run python to see if the theme is installed
  execute_process(COMMAND ${Python_EXECUTABLE} -c
                          "import sphinx_bootstrap_theme"
                  OUTPUT_VARIABLE SPHINX_BOOTSTRAP_THEME_OUT
                  ERROR_VARIABLE SPHINX_BOOTSTRAP_THEME_ERR
                  OUTPUT_STRIP_TRAILING_WHITESPACE
                  ERROR_STRIP_TRAILING_WHITESPACE)
  if(SPHINX_BOOTSTRAP_THEME_ERR)
    message(ERROR " Did not find sphinx_bootstrap_theme")
    message(STATUS "${Python_EXECUTABLE} -c \"import sphinx_bootstrap_theme\"")
    message(STATUS "${SPHINX_BOOTSTRAP_THEME_ERR}")
    message(
      FATAL_ERROR
        " Install instructions at https://pypi.python.org/pypi/sphinx-bootstrap-theme/"
      )
189
  endif()
190
191
192

  add_subdirectory(dev-docs)
  add_subdirectory(docs)
193
endif()
194

195
# System test data target
196
add_subdirectory(Testing/SystemTests/scripts)
197

198
if(COVERALLS)
199
  get_property(ALL_SRCS GLOBAL PROPERTY COVERAGE_SRCS)
200
201
202
203
204
205
  set(SRCS_FILE "")
  foreach(SRC ${ALL_SRCS})
    set(SRCS_FILE "${SRCS_FILE}\n${SRC}")
  endforeach()
  # remove initial \n
  string(SUBSTRING ${SRCS_FILE}
206
207
208
209
                   1
                   -1
                   SRCS_FILE)
  set(SRCS_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/sources.txt")
210
  file(WRITE ${SRCS_FILENAME} ${SRCS_FILE})
211
  coveralls_setup(${SRCS_FILENAME} OFF "${CMAKE_SOURCE_DIR}/buildconfig/CMake")
212
213
endif()

214
# Installation settings
215

216
217
218
219
220
221
222
223
224
225
# Install the files (.desktop and icon) to create a menu items
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
  function(uppercase_first_letter output_var input)
  string(LENGTH ${input} _inputlen)
  string(TOUPPER ${input} _allupper)
  string(SUBSTRING ${_allupper} 0 1 _first)
  string(SUBSTRING ${input} 1 ${_inputlen} _rest)
  set(${output_var} ${_first}${_rest} PARENT_SCOPE)
  endfunction()

226
  function(install_desktop_files filename app_name exec_cmd icon_file icon_install_file)
227
228
    set(DESKTOP_NAME ${app_name})
    set(DESKTOP_EXEC_CMD ${exec_cmd})
229
    get_filename_component(DESKTOP_ICON ${icon_install_file} NAME_WE)
230
231
232
233
234
235
236
237
238
    set(_output_file ${CMAKE_CURRENT_BINARY_DIR}/${filename}.install)
    configure_file(
      ${CMAKE_CURRENT_SOURCE_DIR}/installers/LinuxInstaller/launcher-template.desktop.in
      ${_output_file} @ONLY)
    install(FILES ${_output_file}
            DESTINATION /usr/share/applications
            RENAME ${filename})
    install(FILES ${icon_file}
            DESTINATION /usr/share/pixmaps
239
            RENAME ${icon_install_file})
240
241
  endfunction()

242
243
244
245
246
247
248
249
  set(_icon_suffix)
  if(CPACK_PACKAGE_SUFFIX)
    if (${CPACK_PACKAGE_SUFFIX} STREQUAL "nightly" OR
        ${CPACK_PACKAGE_SUFFIX} STREQUAL "unstable")
      set(_icon_suffix ${CPACK_PACKAGE_SUFFIX})
    endif()
  endif()

250
251
252
253
254
  set( IMAGES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/images )
  set(_app_name_suffix)
  if(CPACK_PACKAGE_SUFFIX)
    uppercase_first_letter(_app_name_suffix ${CPACK_PACKAGE_SUFFIX})
  endif()
255
256
257

  if(ENABLE_WORKBENCH)
    set(_icon_filename ${IMAGES_DIR}/mantid_workbench)
258
259
    if(_icon_suffix)
      set(_icon_filename ${_icon_filename}${_icon_suffix})
260
261
    endif()
    install_desktop_files(mantidworkbench${CPACK_PACKAGE_SUFFIX}.desktop
262
                          "Mantid Workbench ${_app_name_suffix}"
263
                          ${CMAKE_INSTALL_PREFIX}/bin/mantidworkbench
264
265
                          ${_icon_filename}.png
                          mantid_workbench${CPACK_PACKAGE_SUFFIX}.png)
266
  endif()
267
268
endif()

269
270
271
# THIS MUST BE THE LAST SUB_DIRECTORY ADDED. See
# Framework/PostInstall/CMakeLists for an explanation
add_subdirectory(Framework/PostInstall)
272
273

# Conda
274
option(ENABLE_CONDA "Switch to enable conda package generation")
275
276
277
if(ENABLE_CONDA)
  include(conda)
endif(ENABLE_CONDA)
278

279
280
281
# CPack settings

# Keep this in a defaulted-to-off option
282
option(ENABLE_CPACK "Switch to enable CPack package generation")
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
if(ENABLE_CPACK)
  include(CPackCommon)

  # Mac package settings
  set(CPACK_RESOURCE_FILE_LICENSE
      ${CMAKE_SOURCE_DIR}/installers/WinInstaller/License.txt)

  if(CMAKE_HOST_WIN32)
    include(WindowsNSIS)
  elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
    include(CPackLinuxSetup)

    # rhel requirements - only used if package requested is rpm
    set(
      CPACK_RPM_PACKAGE_REQUIRES
298
299
300
301
302
303
304
      "boost169-date-time,"
      "boost169-regex,"
      "boost169-serialization,"
      "boost169-filesystem,"
      "boost169-system,"
      "nexus >= 4.3.1,gsl,glibc,muParser,tbb,librdkafka,"
      "OCE-draw,OCE-foundation,OCE-modeling,OCE-ocaf,OCE-visualization,"
305
306
307
308
      "poco-crypto,poco-data,poco-mysql,poco-sqlite,poco-odbc,poco-util,poco-xml,poco-zip,poco-net,poco-netssl,poco-foundation,"
      "hdf,hdf5,jsoncpp >= 0.7.0")
    if(ENABLE_WORKBENCH)
      set(CPACK_RPM_PACKAGE_REQUIRES
309
          "${CPACK_RPM_PACKAGE_REQUIRES},qt5-qtbase,qscintilla-qt5")
310
    endif()
Martyn Gigg's avatar
Martyn Gigg committed
311
312
313
314
315
316
317
318
319
320
321
322
323
    # python requirements
    set(
      CPACK_RPM_PACKAGE_REQUIRES
      "${CPACK_RPM_PACKAGE_REQUIRES},"
      "boost169-python3,"
      "python36-numpy,python36-scipy,python36-h5py,python36-PyCifRW,"
      "python36-six,python36-PyYAML,python36-requests,python36-toml,"
      "python36-ipython,python36-ipython-notebook"
    )
    if(ENABLE_WORKBENCH)
      set(CPACK_RPM_PACKAGE_REQUIRES
          "${CPACK_RPM_PACKAGE_REQUIRES},python36-qt5,python36-QtPy,"
          "python36-matplotlib-qt5,python36-psutil,python36-ipython-gui")
324
    endif()
325

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
    string(REPLACE ";"
                   ","
                   CPACK_RPM_PACKAGE_REQUIRES
                   ${CPACK_RPM_PACKAGE_REQUIRES}) # fix up the fact that it was
                                                  # made as an array
    string(REPLACE ",,"
                   ","
                   CPACK_RPM_PACKAGE_REQUIRES
                   ${CPACK_RPM_PACKAGE_REQUIRES})

    # ubuntu requirements - only used if package requested is deb
    set(
      CPACK_DEBIAN_PACKAGE_DEPENDS
      "libboost-date-time${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION},"
      "libboost-regex${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION},"
      "libboost-python${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION},"
      "libboost-serialization${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION},"
      "libboost-filesystem${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION},"
      "libnexus0v5 (>= 4.3),"
      "libjsoncpp1 (>=0.7.0),"
      "libmuparser2v5,"
      "libtbb2,"
      "librdkafka1,librdkafka++1,"
      "libpocofoundation${POCO_SOLIB_VERSION},libpocoutil${POCO_SOLIB_VERSION},libpoconet${POCO_SOLIB_VERSION},libpoconetssl${POCO_SOLIB_VERSION},libpococrypto${POCO_SOLIB_VERSION},libpocoxml${POCO_SOLIB_VERSION}"
      )
351

Martyn Gigg's avatar
Martyn Gigg committed
352
    if("${UNIX_CODENAME}" STREQUAL "bionic")
353
354
355
356
357
358
359
360
361
      set(CPACK_DEBIAN_PACKAGE_DEPENDS
          "${CPACK_DEBIAN_PACKAGE_DEPENDS},libgsl23,"
          "liboce-foundation11,liboce-modeling11,"
          "libqscintilla2-qt4-13,"
          "jupyter-notebook,"
          "libhdf5-cpp-100")
      if(ENABLE_WORKBENCH)
        set(CPACK_DEBIAN_PACKAGE_DEPENDS
            "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqscintilla2-qt5-13")
362
      endif()
363
    elseif ( "${UNIX_DIST}" MATCHES "Ubuntu" )
Martyn Gigg's avatar
Martyn Gigg committed
364
      message(WARNING "Unsupported Debian-like OS: ${UNIX_CODENAME}. Packaging is unlikely to work correctly.")
365
    endif()
Martyn Gigg's avatar
Martyn Gigg committed
366
367
368
369
370
371
372
373
374
375
376
377
378
379
    # python requirements
    set(CPACK_DEBIAN_PACKAGE_DEPENDS
        "${CPACK_DEBIAN_PACKAGE_DEPENDS},python3-h5py,"
        "python3-numpy,"
        "python3-requests,"
        "python3-sip,"
        "python3-six,"
        "python3-matplotlib,"
        "python3-qtpy,"
        "python3-scipy,"
        "python3-toml,"
        "python3-pycifrw (>= 4.2.1),"
        "python3-yaml,"
        "ipython3-qtconsole") # transitional package for bionic
380

Martyn Gigg's avatar
Martyn Gigg committed
381
    if(ENABLE_WORKBENCH)
382
      set(CPACK_DEBIAN_PACKAGE_DEPENDS
Martyn Gigg's avatar
Martyn Gigg committed
383
          "${CPACK_DEBIAN_PACKAGE_DEPENDS},python3-pyqt5,python3-psutil")
384
    endif()
Martyn Gigg's avatar
Martyn Gigg committed
385

386
387
388
389
390
391
392
393
394
395
396
    # parse list to string required for deb package
    string(REPLACE ";"
                   ","
                   CPACK_DEBIAN_PACKAGE_DEPENDS
                   ${CPACK_DEBIAN_PACKAGE_DEPENDS}) # fix up the fact that it
                                                    # was made as an array
    string(REPLACE ",,"
                   ","
                   CPACK_DEBIAN_PACKAGE_DEPENDS
                   ${CPACK_DEBIAN_PACKAGE_DEPENDS})
  endif()
397

Mathieu Tillet's avatar
Mathieu Tillet committed
398
399
400
  # soft requirement of jemalloc if selected
  if(USE_JEMALLOC)
    message(STATUS "Adding jemalloc to the package requirements")
401
    set(CPACK_RPM_PACKAGE_REQUIRES
402
        "${CPACK_RPM_PACKAGE_REQUIRES}, jemalloc >= 3.0")
403
    set(CPACK_DEBIAN_PACKAGE_DEPENDS
404
        "${CPACK_DEBIAN_PACKAGE_DEPENDS}, libjemalloc1 (>= 3.0)")
405
406
407
408
409
410
411
412
  endif()

  # run cpack configuration
  include(CPack)
  # let people know what is coming out the other end - must be after cpack
  # generates value for rpm
  message(STATUS "CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}")
endif()