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       "jsbn@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
59  ## Add global definitions
60  # set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY COMPILE_DEFINITIONS
61  AppendDef(MCCODE_NAME="${MCCODE_NAME}")
62	AppendDef(MCCODE_TARNAME="${MCCODE_TARNAME}")
63	AppendDef(MCCODE_VERSION="${MCCODE_VERSION}")
64	AppendDef(MCCODE_STRING="${MCCODE_STRING}")
65	AppendDef(MCCODE_BUGREPORT="www.mcstas.org")
66	AppendDef(MCCODE_URL="")
67
68	# -DCC_HAS_PROTOS=1
69	# -DSTDC_HEADERS=1
70	# -DHAVE_THREADS=\"-DUSE_THREADS\ \$$OPENMP_CFLAGS\ \"
71
72
73
74  ## User-adjustable options
75  option (USE_NEXUS
76    "Support the NEXUS file format" OFF)
77
78  option (USE_THREADS
79    "Enable threading; OBSOLETE: Use MPI/SSH grid feature instead." OFF)
80
81  # update definitions to match choices
82  if (USE_NEXUS)
83    AppendDef(HAVE_NEXUS="-DUSE_NEXUS -lNeXus")
84    AppendDef(USE_NEXUS)
85  endif()
86
87  AppendDefIf(USE_THREADS)
88
89
90  ## Functionality needed to check dependencies
91  include (CheckFunctionExists)
92  include (CheckLibraryExists)
93  include (CheckIncludeFiles)
94
95
96  # A macro for ensuring that all of the values in a variable list are true
97  macro(check_vars vars errmsg)
98    foreach(var ${vars})
99      if(NOT ${var})
100        # throw fatal error when seeing a false value
101        message(FATAL_ERROR ${errmsg})
102      endif()
103    endforeach()
104  endmacro()
105
106
107  ## Check system configuration and dependencies
108
109  # REQUIRED
110  check_function_exists(malloc      HAVE_MALLOC)
111  check_function_exists(realloc     HAVE_REALLOC)
112  check_vars(
113    "${HAVE_MALLOC};${HAVE_REALLOC}"
114    "Missing either malloc or realloc!")
115
116  check_include_files("stdlib.h"    HAVE_STDLIB_H)
117  check_include_files("memory.h"    HAVE_MEMORY_H)
118  check_include_files("unistd.h"    HAVE_UNISTD_H)
119  check_vars(
120    "${HAVE_STDLIB_H};${HAVE_MEMORY_H};${HAVE_UNISTD_H}"
121    "Missing either stdlib.h, memory.h or unistd.h!"
122    )
123
124  check_include_files("inttypes.h"  HAVE_INT_TYPES_H)
125  check_include_files("stdint.h"    HAVE_STD_INT_H)
126  check_vars(
127    "${HAVE_INT_TYPES_H};${HAVE_STD_INT_H}"
128    "Missing either inttypes.h or stdint.h"
129    )
130
131  check_include_files("sys/types.h" HAVE_SYS_TYPES_H)
132  check_include_files("sys/stat.h"  HAVE_SYS_STAT_H)
133  check_vars(
134    "${HAVE_SYS_TYPES_H};${HAVE_SYS_STAT_H}"
135    "Missing either sys/types.h or sys/stat.h"
136    )
137
138  check_include_files("string.h"    HAVE_STRING_H)
139  check_include_files("strings.h"   HAVE_STRINGS_H)
140  check_vars(
141    "${HAVE_STRING_H};${HAVE_STRINGS_H}"
142    "Missing either string.h or strings.h"
143    )
144
145
146  # Check for math
147  check_library_exists(m sqrt "" HAVE_MATH)
148  if(NOT HAVE_MATH)
149    message(FATAL_ERROR "Error: Cannot find sqrt in math library [m]")
150  endif()
151
152
153  # Check for BISON and FLEX (will fail if they are not found)
154  set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/../cmake/Modules/")
155  message("-- Looking for bison and flex")
156  find_package(BISON)
157  find_package(FLEX)
158  message("-- Looking for bison and flex - found")
159
160
161  # OPTIONAL
162  check_function_exists(strcasecmp  HAVE_STRCASECMP)
163  check_function_exists(strcasestr  HAVE_STRCASESTR)
164  check_function_exists(fdopen      HAVE_FDOPEN)
165  check_function_exists(qsort       HAVE_QSORT)
166
167  # Update definitions
168  AppendDefIf(HAVE_STRCASECMP)
169  AppendDefIf(HAVE_STRCASESTR)
170  AppendDefIf(HAVE_FDOPEN)
171  AppendDefIf(HAVE_QSORT)
172
173
174
175  # Create work directory, where all rewritten source files go to
176  # (to support in-place builds)
177  file(MAKE_DIRECTORY "work")
178  file(MAKE_DIRECTORY "work/support")
179
180
181  ## Rules for processing files while expanding macros
182
183  # Macro for configuring every file in a directory
184  # *.in files are configured, while other files are copied unless target exists
185  macro(configure_directory IN_GLOB OUT_DIR)
186    file(GLOB MAN_IN_FILES "" "${IN_GLOB}")
187    foreach(file_in ${MAN_IN_FILES})
188      get_filename_component(filename "${file_in}" NAME)      # /doc/man/example.1.in -> example.1.in
189      string(REGEX MATCH "^(.+)\\.in" matches "${filename}")  # example.1.in -> example.1
190      if(matches)
191        # from IN/doc/man/example.1.in -> OUT/doc/man/example.1
192        configure_file (
193          "${file_in}"
194          "${OUT_DIR}/${CMAKE_MATCH_1}"
195          )
196      else()
197        # do not overwrite files created by configure
198        if(NOT (EXISTS "${OUT_DIR}/${filename}"))
199          file(
200            COPY "${file_in}"
201            DESTINATION "${OUT_DIR}")
202        endif()
203      endif()
204    endforeach()
205  endmacro()
206
207
208  configure_directory ("lib/*" "work/lib")
209  configure_directory ("lib/share/*" "work/lib/share")
210
211  configure_directory ("src/*" "work/src")
212
213  # Generate man pages
214  message("-- Preparing man files")
215  file(MAKE_DIRECTORY "work/doc/man")
216  configure_directory("doc/man/*" "work/doc/man")
217
218
219  ## Include source directories for building
220  include_directories(
221    "${PROJECT_BINARY_DIR}/work/src"             # rewritten files from output dir
222    "${PROJECT_BINARY_DIR}/work/lib/share"       # rewritten library files
223    "${PROJECT_SOURCE_DIR}/${FLAVOR_LIB}/share"  # lib depending on flavor (nlib/xlib)
224  )
225
226
227  ## Generate lex.yy.c with flex
228  add_custom_command(
229    OUTPUT work/src/lex.yy.c
230    COMMAND "${FLEX_EXECUTABLE}" -i "${PROJECT_SOURCE_DIR}/src/instrument.l"
231    WORKING_DIRECTORY work/src
232  )
233
234
235  ## Generate instrument.tab.{h,c} with bison
236  add_custom_command(
237    OUTPUT work/src/instrument.tab.h work/src/instrument.tab.c
238    COMMAND "${BISON_EXECUTABLE}" -v -d "${PROJECT_SOURCE_DIR}/src/instrument.y"
239    WORKING_DIRECTORY work/src
240  )
241
242  # Handling of system-provided random functions on windows -
243  # needed only in the link step for mccode and -format
244  if(WINDOWS)
245    AppendDef(random=rand)
246    AppendDef(srandom=srand)
247  endif()
248
249  ## Build executable for flavor
250  add_executable(
251	  ${FLAVOR}
252	  work/src/cexp.c
253	  work/src/cogen.c
254	  work/src/coords.c
255	  work/src/debug.c
256    work/src/file.c
257	  work/src/list.c
258    work/src/mccode.h
259    work/src/memory.c
260 	  work/src/port.c
261	  work/src/port.h
262	  work/src/symtab.c
263
264    # files generated with flex and bison
265 	  work/src/lex.yy.c
266    work/src/instrument.tab.h
267    work/src/instrument.tab.c
268  )
269
270
271  ## Build McFormat executable
272  add_executable(
273	  "${FLAVOR_FMT}"
274	  work/src/mcformat.c
275  )
276  ## McFormat needs to be linked against m
277  target_link_libraries(${FLAVOR_FMT} m)
278
279
280  ## Add install targets
281  include(MCUtil)
282  set(WORK "${PROJECT_BINARY_DIR}/work")
283
284  # Flavor-specific library
285  installLib("${PROJECT_SOURCE_DIR}/${FLAVOR_LIB}/")
286
287  # Shared library, lib
288  installLib("${WORK}/lib/")
289
290  if(NOT WINDOWS)
291    # Man pages
292    install (
293      FILES "${WORK}/doc/man/${FLAVOR}.1"
294      DESTINATION "man/man1"
295      RENAME "${FLAVOR}.1"
296      )
297    install (
298      FILES "${WORK}/doc/man/${FLAVOR_FMT}.1"
299      DESTINATION "man/man1"
300      RENAME "${FLAVOR_FMT}.1"
301      )
302    # Binaries
303    install (
304      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR}${DOT_EXE_SUFFIX}"
305      DESTINATION ${FLAVOR}/${MCCODE_VERSION}/bin
306    )
307    install (
308      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR_FMT}${DOT_EXE_SUFFIX}"
309      DESTINATION ${FLAVOR}/${MCCODE_VERSION}/bin
310    )
311
312    foreach (name environment module)
313      configure_file(
314	      cmake/support/run-scripts/${name}.in
315	      work/support/${name}
316	      @ONLY)
317      install(PROGRAMS ${WORK}/support/${name} DESTINATION ${FLAVOR}/${MCCODE_VERSION}/)
318    endforeach()
319
320  endif()
321
322  if(WINDOWS)
323    # Generate and install Windows setup scripts
324    foreach (name mccodeenv.bat mccodeguigo.bat mccodego.bat mccodetest.bat)
325      configure_file(
326	      cmake/support/run-scripts/${name}.in
327	      work/support/${name}
328	      )
329      install(PROGRAMS ${WORK}/support/${name} DESTINATION ${bin})
330    endforeach()
331
332    # Python related batches special handling
333    foreach (name run-py.bat plot-chaco-py.bat plot-matplotlib-py.bat display-x3d-py.bat display-matplotlib-py.bat display-R-py.bat display-vtk-py.bat)
334      configure_file(
335	      cmake/support/run-scripts/${name}.in
336	      work/support/${MCCODE_PREFIX}${name}
337	      )
338      install(PROGRAMS ${WORK}/support/${MCCODE_PREFIX}${name} DESTINATION ${bin})
339    endforeach()
340
341    # Binaries
342    install (
343      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR}${DOT_EXE_SUFFIX}"
344      DESTINATION ${bin}
345    )
346    install (
347      PROGRAMS "${PROJECT_BINARY_DIR}/${FLAVOR_FMT}${DOT_EXE_SUFFIX}"
348      DESTINATION ${bin}
349    )
350
351    install(PROGRAMS
352      cmake/support/install-scripts/postsetup.bat
353      DESTINATION ${bin}
354      )
355
356    install(PROGRAMS
357      cmake/support/run-scripts/mpicc.bat
358      DESTINATION ${bin}
359      )
360
361  endif()
362
363
364endmacro(installMCCODE)
365