1# InstallMCCODE
2# A module for configuring and installing McStas / McXtrace
3# The following macros needs to be defined before calling this:
4# NAME, FLAVOR, FLAVOR_FMT, FLAVOR_LIB,
5# MCCODE_PARTICLE, MCCODE_LIBENV, MCCODE_PROJECT
6# MAJOR, MINOR, MCCODE_VERSION, MCCODE_NAME, MCCODE_DATE,
7# MCCODE_STRING MCCODE_TARNAME
8#
9# After doing so (using set()) this module can be included with
10
11macro(AppendDef def)
12    set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND
13      PROPERTY COMPILE_DEFINITIONS
14      ${def}
15      )
16endmacro(AppendDef)
17
18macro(AppendDefIf def)
19  if(${def})
20    AppendDef(${def}=${def})
21  endif()
22endmacro(AppendDefIf)
23
24
25macro(installMCCODE)
26
27  # Ignore CMake warning when setting "-Denable_mcstas=1"
28  option(enable_${FLAVOR} "This option is here for compatibility only." On)
29  if (NOT enable_${FLAVOR})
30    message(FATAL_ERROR "Cannot deselect ${FLAVOR} flavor.")
31  endif()
32
33  ## CPack configuration
34  set(CPACK_PACKAGE_NAME          "${FLAVOR}-${MCCODE_VERSION}")
35  set(CPACK_RESOURCE_FilE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../COPYING")
36  set(CPACK_PACKAGE_CONTACT       "pkwi@fysik.dtu.dk")
37
38  ## Package versioning
39  set(MAJOR "1")
40  set(MINOR "0")
41
42  set(CPACK_PACKAGE_VERSION       "${MAJOR}.${MINOR}")
43  set(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR}")
44  set(CPACK_PACKAGE_VERSION_MINOR "${MINOR}")
45
46  ## Debian
47  set(CPACK_DEBIAN_PACKAGE_DEPENDS       "build-essential, bash")
48  set(CPACK_DEBIAN_PACKAGE_RECOMMENDS    "${FLAVOR}-comps-${MCCODE_VERSION}")
49  set(CPACK_DEBIAN_PACKAGE_CONFLICTS    "${FLAVOR}-2.1rc1")
50  set(CPACK_DEBIAN_PACKAGE_SUGGESTS      "openmpi-bin, openmpi-dev")
51
52  ## NSIS
53  set(CPACK_NSIS_PACKAGE_NAME "${MCCODE_STRING}")
54  set(CPACK_NSIS_DISPLAY_NAME "${MCCODE_STRING}")
55
56  include(CPack)
57
58  string(TIMESTAMP MCCODE_YEAR "%Y")
59
60  ## Add global definitions
61  # set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY COMPILE_DEFINITIONS
62  AppendDef(MCCODE_NAME="${MCCODE_NAME}")
63	AppendDef(MCCODE_TARNAME="${MCCODE_TARNAME}")
64	AppendDef(MCCODE_VERSION="${MCCODE_VERSION}")
65	AppendDef(MCCODE_STRING="${MCCODE_STRING}")
66        AppendDef(MCCODE_BUGREPORT="www.${MCCODE_TARNAME}.org")
67	AppendDef(MCCODE_URL="")
68
69	# -DCC_HAS_PROTOS=1
70	# -DSTDC_HEADERS=1
71	# -DHAVE_THREADS=\"-DUSE_THREADS\ \$$OPENMP_CFLAGS\ \"
72
73
74
75  ## User-adjustable options
76  option (USE_NEXUS
77    "Support the NEXUS file format" OFF)
78
79  option (USE_THREADS
80    "Enable threading; OBSOLETE: Use MPI/SSH grid feature instead." OFF)
81
82  # update definitions to match choices
83  if (USE_NEXUS)
84    AppendDef(HAVE_NEXUS="-DUSE_NEXUS -lNeXus")
85    AppendDef(USE_NEXUS)
86  endif()
87
88  AppendDefIf(USE_THREADS)
89
90
91  ## Functionality needed to check dependencies
92  include (CheckFunctionExists)
93  include (CheckLibraryExists)
94  include (CheckIncludeFiles)
95
96
97  # A macro for ensuring that all of the values in a variable list are true
98  macro(check_vars vars errmsg)
99    foreach(var ${vars})
100      if(NOT ${var})
101        # throw fatal error when seeing a false value
102        message(FATAL_ERROR ${errmsg})
103      endif()
104    endforeach()
105  endmacro()
106
107
108  ## Check system configuration and dependencies
109
110  # REQUIRED
111  check_function_exists(malloc      HAVE_MALLOC)
112  check_function_exists(realloc     HAVE_REALLOC)
113  check_vars(
114    "${HAVE_MALLOC};${HAVE_REALLOC}"
115    "Missing either malloc or realloc!")
116
117  check_include_files("stdlib.h"    HAVE_STDLIB_H)
118  check_include_files("memory.h"    HAVE_MEMORY_H)
119  check_include_files("unistd.h"    HAVE_UNISTD_H)
120  check_vars(
121    "${HAVE_STDLIB_H};${HAVE_MEMORY_H};${HAVE_UNISTD_H}"
122    "Missing either stdlib.h, memory.h or unistd.h!"
123    )
124
125  check_include_files("inttypes.h"  HAVE_INT_TYPES_H)
126  check_include_files("stdint.h"    HAVE_STD_INT_H)
127  check_vars(
128    "${HAVE_INT_TYPES_H};${HAVE_STD_INT_H}"
129    "Missing either inttypes.h or stdint.h"
130    )
131
132  check_include_files("sys/types.h" HAVE_SYS_TYPES_H)
133  check_include_files("sys/stat.h"  HAVE_SYS_STAT_H)
134  check_vars(
135    "${HAVE_SYS_TYPES_H};${HAVE_SYS_STAT_H}"
136    "Missing either sys/types.h or sys/stat.h"
137    )
138
139  check_include_files("string.h"    HAVE_STRING_H)
140  check_include_files("strings.h"   HAVE_STRINGS_H)
141  check_vars(
142    "${HAVE_STRING_H};${HAVE_STRINGS_H}"
143    "Missing either string.h or strings.h"
144    )
145
146
147  # Check for math
148  check_include_files("math.h" HAVE_MATH_H)
149  if(NOT HAVE_MATH_H)
150    message(FATAL_ERROR "Error: Cannot find math.h [m]")
151  endif()
152
153
154  # Check for BISON and FLEX (will fail if they are not found)
155  set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/../cmake/Modules/")
156  message("-- Looking for bison and flex")
157  find_package(BISON)
158  find_package(FLEX)
159  message("-- Looking for bison and flex - found")
160
161
162  # OPTIONAL
163  check_function_exists(strcasecmp  HAVE_STRCASECMP)
164  check_function_exists(strcasestr  HAVE_STRCASESTR)
165  check_function_exists(fdopen      HAVE_FDOPEN)
166  check_function_exists(qsort       HAVE_QSORT)
167
168  # Update definitions
169  AppendDefIf(HAVE_STRCASECMP)
170  AppendDefIf(HAVE_STRCASESTR)
171  AppendDefIf(HAVE_FDOPEN)
172  AppendDefIf(HAVE_QSORT)
173
174
175
176  # Create work directory, where all rewritten source files go to
177  # (to support in-place builds)
178  file(MAKE_DIRECTORY "work")
179  file(MAKE_DIRECTORY "work/support")
180
181
182  ## Rules for processing files while expanding macros
183
184  # Macro for configuring every file in a directory
185  # *.in files are configured, while other files are copied unless target exists
186  macro(configure_directory IN_GLOB OUT_DIR)
187    file(GLOB MAN_IN_FILES "" "${IN_GLOB}")
188    foreach(file_in ${MAN_IN_FILES})
189      get_filename_component(filename "${file_in}" NAME)      # /doc/man/example.1.in -> example.1.in
190      string(REGEX MATCH "^(.+)\\.in" matches "${filename}")  # example.1.in -> example.1
191      if(matches)
192        # from IN/doc/man/example.1.in -> OUT/doc/man/example.1
193        configure_file (
194          "${file_in}"
195          "${OUT_DIR}/${CMAKE_MATCH_1}"
196          )
197      else()
198        # do not overwrite files created by configure
199        if(NOT (EXISTS "${OUT_DIR}/${filename}"))
200          file(
201            COPY "${file_in}"
202            DESTINATION "${OUT_DIR}")
203        endif()
204      endif()
205    endforeach()
206  endmacro()
207
208
209  configure_directory ("lib/*" "work/lib")
210  configure_directory ("lib/share/*" "work/lib/share")
211
212  configure_directory ("src/*" "work/src")
213
214  ## Include source directories for building
215  include_directories(
216    "${PROJECT_BINARY_DIR}/work/src"             # rewritten files from output dir
217    "${PROJECT_BINARY_DIR}/work/lib/share"       # rewritten library files
218    "${PROJECT_SOURCE_DIR}/${FLAVOR_LIB}/share"  # lib depending on flavor (nlib/xlib)
219  )
220
221
222  ## Generate lex.yy.c with flex
223  add_custom_command(
224    OUTPUT work/src/lex.yy.c
225    COMMAND "${FLEX_EXECUTABLE}" -i "${PROJECT_SOURCE_DIR}/src/instrument.l"
226    WORKING_DIRECTORY work/src
227  )
228
229
230  ## Generate instrument.tab.{h,c} with bison
231  add_custom_command(
232    OUTPUT work/src/instrument.tab.h work/src/instrument.tab.c
233    COMMAND "${BISON_EXECUTABLE}" -v -d "${PROJECT_SOURCE_DIR}/src/instrument.y"
234    WORKING_DIRECTORY work/src
235  )
236
237  # Handling of system-provided random functions on windows -
238  # needed only in the link step for mccode and -format
239  if(WINDOWS)
240    AppendDef(random=rand)
241    AppendDef(srandom=srand)
242  endif()
243
244  ## Build executable for flavor
245  add_executable(
246	  ${FLAVOR}
247	  work/src/cexp.c
248	  work/src/cogen.c
249	  work/src/coords.c
250	  work/src/debug.c
251    work/src/file.c
252	  work/src/list.c
253    work/src/mccode.h
254    work/src/memory.c
255 	  work/src/port.c
256	  work/src/port.h
257	  work/src/symtab.c
258
259    # files generated with flex and bison
260 	  work/src/lex.yy.c
261    work/src/instrument.tab.h
262    work/src/instrument.tab.c
263  )
264
265
266  ## Build McFormat executable
267  add_executable(
268	  "${FLAVOR_FMT}"
269	  work/src/mcformat.c
270  )
271  ## McFormat needs to be linked against m
272  target_link_libraries(${FLAVOR_FMT} m)
273
274  ## Add install targets
275  include(MCUtil)
276  set(WORK "${PROJECT_BINARY_DIR}/work")
277
278  # Flavor-specific library
279  installLib("${PROJECT_SOURCE_DIR}/${FLAVOR_LIB}/")
280
281  # Shared library, lib
282  installLib("${WORK}/lib/")
283
284  if(NOT WINDOWS)
285    # Binaries
286    install (
287      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR}${DOT_EXE_SUFFIX}"
288      DESTINATION ${FLAVOR}/${MCCODE_VERSION}/bin
289    )
290    install (
291      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR_FMT}${DOT_EXE_SUFFIX}"
292      DESTINATION ${FLAVOR}/${MCCODE_VERSION}/bin
293    )
294
295    foreach (name environment module)
296      configure_file(
297	      cmake/support/run-scripts/${name}.in
298	      work/support/${name}
299	      @ONLY)
300      install(PROGRAMS ${WORK}/support/${name} DESTINATION ${FLAVOR}/${MCCODE_VERSION}/)
301    endforeach()
302    install(PROGRAMS ${WORK}/support/postinst DESTINATION ${FLAVOR}/${MCCODE_VERSION}/bin/)
303    install(PROGRAMS ${WORK}/support/${FLAVOR}_errmsg DESTINATION ${FLAVOR}/${MCCODE_VERSION}/bin/)
304  endif()
305
306  if(WINDOWS)
307    # Generate and install Windows setup scripts
308    foreach (name mccodeenv.bat mccodeenv.m mccodego.bat mccodetest.bat)
309      configure_file(
310	      cmake/support/run-scripts/${name}.in
311	      work/support/${name}
312	      )
313      install(PROGRAMS ${WORK}/support/${name} DESTINATION ${bin})
314    endforeach()
315
316    # Python/Perl related batches special handling
317    foreach (name run.bat run-pl.bat doc.bat doc-pl.bat plot.bat plot-pl.bat display.bat display-pl.bat gui.bat guistart.bat gui-pl.bat plot-pyqtgraph.bat plot-matplotlib.bat plot-matlab.bat display-webgl.bat display-pyqtgraph.bat display-mantid.bat)
318      configure_file(
319	      cmake/support/run-scripts/${name}.in
320	      work/support/${MCCODE_PREFIX}${name}
321	      )
322      install(PROGRAMS ${WORK}/support/${MCCODE_PREFIX}${name} DESTINATION ${bin})
323    endforeach()
324
325    # Binaries
326    install (
327      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR}${DOT_EXE_SUFFIX}"
328      DESTINATION ${bin}
329    )
330    install (
331      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR_FMT}${DOT_EXE_SUFFIX}"
332      DESTINATION ${bin}
333    )
334
335    install(PROGRAMS
336      cmake/support/install-scripts/postsetup.bat
337      DESTINATION ${bin}
338      )
339
340    install(PROGRAMS
341      cmake/support/run-scripts/mpicc.bat
342      DESTINATION ${bin}
343      )
344
345  endif()
346
347
348endmacro(installMCCODE)
349