ENH: slightly improve foam_compile_asy function
[freefoam.git] / CMake / FOAMUtilities.cmake
blob72ea94cd575752f3e8e8f8f57d437fdb9489c7e7
2 #-------------------------------------------------------------------------------
3 #               ______                _     ____          __  __
4 #              |  ____|             _| |_  / __ \   /\   |  \/  |
5 #              | |__ _ __ ___  ___ /     \| |  | | /  \  | \  / |
6 #              |  __| '__/ _ \/ _ ( (| |) ) |  | |/ /\ \ | |\/| |
7 #              | |  | | |  __/  __/\_   _/| |__| / ____ \| |  | |
8 #              |_|  |_|  \___|\___|  |_|   \____/_/    \_\_|  |_|
10 #                   FreeFOAM: The Cross-Platform CFD Toolkit
12 # Copyright (C) 2008-2010 Michael Wild <themiwi@users.sf.net>
13 #                         Gerber van der Graaf <gerber_graaf@users.sf.net>
14 #-------------------------------------------------------------------------------
15 # License
16 #   This file is part of FreeFOAM.
18 #   FreeFOAM is free software; you can redistribute it and/or modify it
19 #   under the terms of the GNU General Public License as published by the
20 #   Free Software Foundation; either version 2 of the License, or (at your
21 #   option) any later version.
23 #   FreeFOAM is distributed in the hope that it will be useful, but WITHOUT
24 #   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 #   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26 #   for more details.
28 #   You should have received a copy of the GNU General Public License
29 #   along with FreeFOAM; if not, write to the Free Software Foundation,
30 #   Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 # Description
33 #   Functions to configure build and install FOAM libraries and executables.
34 #   Refer to FOAMUse.cmake for the documentation of these functions.
36 #   THE FIRST LINE OF THIS FILE IS INTENTIONALLY LEFT BLANK!
38 #-------------------------------------------------------------------------------
40 # CAUTION: Include this file only once!
42 # include-guard
43 if(NOT __FOAMADDTARGET_INCLUDED)
44 set(__FOAMADDTARGET_INCLUDED DEFINED)
46 # helper to set defaults for a variable
47 function(_foam_set_default var defvar def)
48   if(DEFINED ${defvar})
49     set(val ${${defvar}})
50   else()
51     set(val ${def})
52   endif()
53   set(${var} ${val} PARENT_SCOPE)
54 endfunction()
56 function(foam_parse_arguments prefix arg_specs option_names)
57   # initialize
58   set(DEFAULT_ARGS)
59   set(maxcount_DEFAULT_ARGS -1)
60   set(arg_names)
61   foreach(arg_spec ${arg_specs})
62     set(arg_name ${arg_spec})
63     set(arg_maxcount -1)
64     if(arg_spec MATCHES "^([^:]+)(:([0-9]+))?$")
65       set(arg_name ${CMAKE_MATCH_1})
66       if(CMAKE_MATCH_2)
67         set(arg_maxcount ${CMAKE_MATCH_3})
68       endif()
69     endif()
70     set(result_${arg_name})
71     set(maxcount_${arg_name} ${arg_maxcount})
72     list(APPEND arg_names ${arg_name})
73   endforeach()
74   foreach(option ${option_names})
75     set(result_${option} FALSE)
76   endforeach()
78   # parse
79   set(current_arg_name DEFAULT_ARGS)
80   set(current_arg_count 0)
81   foreach(arg IN LISTS ARGN)
82     if(arg STREQUAL "")
83       set(is_arg_name -1)
84     else()
85       list(FIND arg_names "${arg}" is_arg_name)
86     endif()
87     if(is_arg_name GREATER -1)
88       set(current_arg_name ${arg})
89       set(current_arg_count 0)
90     else()
91       if(arg STREQUAL "")
92         set(is_option -1)
93       else()
94         list(FIND option_names "${arg}" is_option)
95       endif()
96       if(is_option GREATER -1)
97         set(result_${arg} TRUE)
98       elseif(maxcount_${current_arg_name} LESS 0 OR
99           current_arg_count LESS ${maxcount_${current_arg_name}})
100         list(APPEND result_${current_arg_name} "${arg}")
101         math(EXPR current_arg_count "${current_arg_count} + 1")
102       else()
103         list(APPEND result_DEFAULT_ARGS "${arg}")
104       endif()
105     endif()
106   endforeach()
107   # propagate to caller scope
108   foreach(arg_name DEFAULT_ARGS ${arg_names})
109     set(${prefix}_${arg_name} "${result_${arg_name}}" PARENT_SCOPE)
110   endforeach()
111   foreach(option ${option_names})
112     set(${prefix}_${option} "${result_${option}}" PARENT_SCOPE)
113   endforeach()
114 endfunction()
116 function(foam_add_library name)
117   # defaults
118   _foam_set_default(export_set_name FOAM_EXPORT_SET_NAME ${PROJECT_NAME}LibraryDepends)
119   _foam_set_default(enable_export_set FOAM_ENABLE_EXPORT_SET TRUE)
120   _foam_set_default(build_framework FOAM_BUILD_FRAMEWORKS FALSE)
121   _foam_set_default(create_include_wrappers FOAM_CREATE_INCLUDE_WRAPPERS FALSE)
122   # argument parsing
123   foam_parse_arguments(_fal "PUBLIC_HEADERS;EXPORT:1" "SKIP_EXPORT" ${ARGN})
124   # check arguments
125   if(_fal_EXPORT AND _fal_SKIP_EXPORT)
126     message(FATAL_ERROR "Cannot specify both EXPORT and SKIP_EXPORT")
127   endif()
128   list(GET _fal_DEFAULT_ARGS 0 lib_type)
129   if(lib_type MATCHES "^(STATIC|SHARED|MODULE)$")
130     list(REMOVE_AT _fal_DEFAULT_ARGS 0)
131   else()
132     set(lib_type)
133   endif()
134   # check SRCS
135   set(SRCS ${_fal_DEFAULT_ARGS})
136   set(HDRS ${_fal_PUBLIC_HEADERS})
137   if(NOT SRCS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/files.cmake)
138     include(${CMAKE_CURRENT_SOURCE_DIR}/files.cmake)
139   endif()
140   if(NOT SRCS)
141     message(FATAL_ERROR "At least one source file required")
142   endif()
143   if(FOAM_HAS_FLEX_SOURCES)
144     # check for .L sources
145     foam_check_and_compile_flex(SRCS)
146   endif()
147   if(create_include_wrappers AND HDRS)
148     # create the include wrappers
149     foam_create_include_wrappers(${name} ${HDRS})
150   endif()
151   # add library
152   add_library(${name} ${lib_type} ${SRCS})
153   # set properties
154   set_target_properties(${name} PROPERTIES
155     FRAMEWORK ${build_framework}
156     )
157   if(DEFINED FOAM_VERSION_FULL)
158     set_target_properties(${name} PROPERTIES
159       VERSION ${FOAM_VERSION_FULL})
160   endif()
161   if(DEFINED FOAM_SOVERSION)
162     set_target_properties(${name} PROPERTIES
163       SOVERSION ${FOAM_SOVERSION}
164       FRAMEWORK_VERSION ${FOAM_SOVERSION})
165   endif()
166   if(DEFINED FOAM_FRAMEWORK_INSTALL_NAME_DIR)
167     set_target_properties(${name} PROPERTIES
168       INSTALL_NAME_DIR "${FOAM_FRAMEWORK_INSTALL_NAME_DIR}")
169   endif()
170   get_target_property(_VER ${name} VERSION)
171   get_target_property(_SOVER ${name} SOVERSION)
172   if(HDRS)
173     set_target_properties(${name} PROPERTIES
174       PUBLIC_HEADER "${HDRS}"
175       )
176   endif()
177   # add to build-tree export
178   if(NOT _fal_SKIP_EXPORT AND enable_export_set)
179     foam_add_target_to_build_tree_export(${export_set_name} ${name})
180   endif()
181   # set properties for Doxygen filtering
182   set_property(GLOBAL APPEND PROPERTY FOAM_DOXYGEN_LIBRARIES "${name}")
183   set_property(GLOBAL PROPERTY FOAM_DOXYGEN_${name}_LIBRARY_DIR
184     "${CMAKE_CURRENT_SOURCE_DIR}")
185 endfunction()
187 function(foam_add_executable name)
188   # defaults
189   _foam_set_default(do_doc_index FOAM_ENABLE_DOC_INDEX TRUE)
190   set(do_manpage TRUE)
191   # argument parsing
192   foam_parse_arguments(_fae
193     "OUTPUT_NAME:1;DOC_SRC:1;APP_SECTION:1"
194     "SKIP_DOC_INDEX;SKIP_MANPAGE"
195     ${ARGN})
196   # find output name
197   if(NOT _fae_OUTPUT_NAME)
198     set(_fae_OUTPUT_NAME ${FOAM_EXE_PREFIX}${name})
199   endif()
200   # find application section
201   if(NOT _fae_APP_SECTION AND DEFINED FOAM_APP_SECTION)
202     set(_fae_APP_SECTION ${FOAM_APP_SECTION})
203   endif()
204   # check SKIP_DOC_INDEX
205   if(_fae_SKIP_DOC_INDEX)
206     set(do_doc_index FALSE)
207   endif()
208   # check SKIP_MANPAGE
209   if(_fae_SKIP_MANPAGE)
210     set(do_manpage FALSE)
211   endif()
212   set(SRCS ${_fae_DEFAULT_ARGS})
213   # check SRCS
214   if(NOT SRCS AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/files.cmake)
215     include(${CMAKE_CURRENT_SOURCE_DIR}/files.cmake)
216   endif()
217   if(NOT SRCS)
218     message(FATAL_ERROR "At least one source file required")
219   endif()
220   # find doc source
221   if(NOT _fae_DOC_SRC)
222     list(GET SRCS 0 _fae_DOC_SRC)
223   endif()
225   if(FOAM_HAS_FLEX_SOURCES)
226     # check for .L sources
227     foam_check_and_compile_flex(SRCS)
228   endif()
229   # add executable
230   add_executable(${name} ${SRCS})
231   # set output name
232   set_target_properties(${name} PROPERTIES
233     OUTPUT_NAME ${_fae_OUTPUT_NAME}
234     )
235   # add to index
236   if(do_doc_index)
237     foam_add_executable_to_doc_index(${_fae_OUTPUT_NAME} ${_fae_DOC_SRC})
238   endif()
239   # create brief description
240   if(_fae_APP_SECTION)
241     foam_create_app_brief(${name} ${_fae_APP_SECTION} "${_fae_DOC_SRC}")
242   endif()
243   # create man page
244   if(do_manpage)
245     foam_create_manpage(${_fae_OUTPUT_NAME} ${_fae_DOC_SRC})
246   endif()
247   # set properties for Doxygen filtering
248   set_property(GLOBAL APPEND PROPERTY FOAM_DOXYGEN_EXECUTABLES "${name}")
249   set_property(GLOBAL PROPERTY FOAM_DOXYGEN_${name}_EXECUTABLE_DIR
250     "${CMAKE_CURRENT_SOURCE_DIR}")
251 endfunction()
253 # purge all export lists...
254 if(DEFINED __FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_SET_NAMES)
255   list(REMOVE_DUPLICATES __FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_SET_NAMES)
256   foreach(e ${__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_SET_NAMES})
257     unset(__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_${e}_targets CACHE)
258   endforeach()
259   unset(__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_SET_NAMES CACHE)
260 endif()
262 function(foam_add_target_to_build_tree_export export_set_name)
263   set(__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_${export_set_name}_targets
264     ${__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_${export_set_name}_targets}
265     ${ARGN}
266     CACHE INTERNAL
267     "Targets to export to the build tree for ${export_set_name}"
268     )
269   set(__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_SET_NAMES
270     ${__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_SET_NAMES}
271     ${export_set_name}
272     CACHE INTERNAL
273     "Build-tree export set names"
274     )
275 endfunction()
277 function(foam_export_targets_to_build_tree export_set)
278   if(ARGC GREATER 1)
279     set(namespace ${ARGV1})
280   elseif(DEFINED FOAM_EXPORT_NAMESPACE)
281     set(namespace ${FOAM_EXPORT_NAMESPACE})
282   else()
283     set(namespace FOAM_)
284   endif()
285   string(REPLACE ";" " " _tmp "${__FOAM_ADD_TARGET_TO_BUILD_TREE_EXPORT_${export_set}_targets}")
286   separate_arguments(_tmp)
287   export(TARGETS ${_tmp}
288     NAMESPACE ${namespace}
289     FILE ${PROJECT_BINARY_DIR}/CMake/${export_set}.cmake
290     )
291 endfunction()
293 function(foam_install_targets)
294   # defaults
295   _foam_set_default(export_set_name FOAM_EXPORT_SET_NAME ${PROJECT_NAME}LibraryDepends)
296   _foam_set_default(enable_export_set FOAM_ENABLE_EXPORT_SET TRUE)
297   _foam_set_default(export_executables FOAM_EXPORT_EXECUTABLES FALSE)
298   _foam_set_default(ARCHIVE_destination FOAM_INSTALL_ARCHIVE_PATH lib/${PROJECT_NAME})
299   _foam_set_default(LIBRARY_destination FOAM_INSTALL_LIBRARY_PATH lib/${PROJECT_NAME})
300   _foam_set_default(RUNTIME_destination FOAM_INSTALL_RUNTIME_PATH libexec/${PROJECT_NAME})
301   _foam_set_default(FRAMEWORK_destination FOAM_INSTALL_FRAMEWORK_PATH /Library/Frameworks)
302   _foam_set_default(PRIVATE_HEADER_destination FOAM_INSTALL_HEADER_PATH include/${PROJECT_NAME})
303   _foam_set_default(PUBLIC_HEADER_destination FOAM_INSTALL_HEADER_PATH include/${PROJECT_NAME})
304   _foam_set_default(ARCHIVE_component FOAM_INSTALL_ARCHIVE_COMPONENT dev)
305   _foam_set_default(LIBRARY_component FOAM_INSTALL_LIBRARY_COMPONENT shlibs)
306   _foam_set_default(RUNTIME_component FOAM_INSTALL_RUNTIME_COMPONENT bin)
307   _foam_set_default(FRAMEWORK_component FOAM_INSTALL_FRAMEWORK_COMPONENT shlibs)
308   _foam_set_default(PRIVATE_HEADER_component FOAM_INSTALL_HEADER_COMPONENT dev)
309   _foam_set_default(PUBLIC_HEADER_component FOAM_INSTALL_HEADER_COMPONENT dev)
310   # argument parsing
311   set(lib_targets)
312   set(exe_targets)
313   set(next_target TRUE)
314   set(next_export FALSE)
315   set(next_destination FALSE)
316   set(next_component FALSE)
317   set(PRIVATE_HEADER_is_default_dest TRUE)
318   set(PUBLIC_HEADER_is_default_dest TRUE)
319   set(install_type)
320   foreach(a ${ARGN})
321     if(a MATCHES
322         "^(ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|(PUBLIC|PRIVATE)_HEADER)$")
323       set(install_type ${a})
324       set(next_target FALSE)
325       if(a MATCHES "^(PUBLIC|PRIVATE)_HEADER$")
326         set(${a}_is_default_dest FALSE)
327       endif()
328     # MUST be second after "a MATCHES ..."
329     elseif(install_type)
330       if(a STREQUAL DESTINATION)
331         set(next_destination TRUE)
332       elseif(a STREQUAL COMPONENT)
333         set(next_component TRUE)
334       elseif(next_destination)
335         set(${install_type}_destination "${a}")
336         set(${install_type}_is_default_dest FALSE)
337         set(next_destination FALSE)
338       elseif(next_component)
339         set(${install_type}_component "${a}")
340         set(next_component FALSE)
341         set(install_type)
342       else()
343         message(FATAL_ERROR
344           "Expected DESTINATION <dir> or COMPONENT <name> after ${install_type}")
345       endif()
346     elseif(a STREQUAL EXPORT)
347       set(next_export TRUE)
348       set(next_target FALSE)
349     elseif(a STREQUAL SKIP_EXPORT)
350       set(enable_export_set FALSE)
351       set(next_target FALSE)
352     elseif(a STREQUAL EXPORT_EXECUTABLES)
353       set(export_executables TRUE)
354       set(next_target FALSE)
355     elseif(next_export)
356       set(export_set_name ${a})
357     elseif(next_target)
358       # split targets into executables and others
359       get_target_property(target_type ${a} TYPE)
360       if(target_type STREQUAL EXECUTABLE)
361         list(APPEND exe_targets ${a})
362       else()
363         list(APPEND lib_targets ${a})
364       endif()
365     else()
366       message(FATAL_ERROR "Unexpected argument '${a}'")
367     endif()
368   endforeach()
369   # set up "EXPORT <export-set>"
370   if(NOT enable_export_set)
371     set(lib_export_str)
372   else()
373     set(lib_export_str EXPORT ${export_set_name})
374   endif()
375   if(export_executables)
376     set(exe_export_str ${lib_export_str})
377   else()
378     set(exe_export_str)
379   endif()
380   if(lib_targets)
381     foreach(t ${lib_targets})
382       # figure out installation directory of headers
383       get_target_property(lib_name ${t} OUTPUT_NAME)
384       if(NOT lib_name)
385         set(lib_name ${t})
386       endif()
387       set(priv_hdr_dest "${PRIVATE_HEADER_destination}")
388       if(NOT PRIVATE_HEADER_is_default_dest)
389         set(priv_hdr_dest "${priv_hdr_dest}/${lib_name}")
390       endif()
391       set(pub_hdr_dest "${PUBLIC_HEADER_destination}")
392       if(PUBLIC_HEADER_is_default_dest)
393         set(pub_hdr_dest "${pub_hdr_dest}/${lib_name}")
394       endif()
395       # install the target
396       install(TARGETS ${t}
397         ${lib_export_str}
398         ARCHIVE        DESTINATION ${ARCHIVE_destination}
399                        COMPONENT ${ARCHIVE_component}
400         LIBRARY        DESTINATION ${LIBRARY_destination}
401                        COMPONENT ${LIBRARY_component}
402         RUNTIME        DESTINATION ${RUNTIME_destination}
403                        COMPONENT ${RUNTIME_component}
404         FRAMEWORK      DESTINATION ${FRAMEWORK_destination}
405                        COMPONENT ${FRAMEWORK_component}
406         PRIVATE_HEADER DESTINATION ${priv_hdr_dest}
407                        COMPONENT ${PRIVATE_HEADER_component}
408         PUBLIC_HEADER  DESTINATION ${pub_hdr_dest}
409                        COMPONENT ${PUBLIC_HEADER_component}
410         )
411     endforeach()
412   endif()
413   if(exe_targets)
414     foreach(t ${exe_targets})
415       install(TARGETS ${t}
416         ${exe_export_str}
417         ARCHIVE        DESTINATION ${ARCHIVE_destination}
418                        COMPONENT ${ARCHIVE_component}
419         LIBRARY        DESTINATION ${LIBRARY_destination}
420                        COMPONENT ${LIBRARY_component}
421         RUNTIME        DESTINATION ${RUNTIME_destination}
422                        COMPONENT ${RUNTIME_component}
423         FRAMEWORK      DESTINATION ${FRAMEWORK_destination}
424                        COMPONENT ${FRAMEWORK_component}
425         PRIVATE_HEADER DESTINATION ${priv_hdr_dest}
426                        COMPONENT ${PRIVATE_HEADER_component}
427         PUBLIC_HEADER  DESTINATION ${pub_hdr_dest}
428                        COMPONENT ${PUBLIC_HEADER_component}
429         )
430     endforeach()
431   endif()
432 endfunction()
434 function(foam_create_include_wrappers libname)
435   # destination directory
436   set(d "${CMAKE_BINARY_DIR}/include/${libname}")
437   # loop over headers
438   foreach(h ${ARGN})
439     # make absolute, with no symlinks (they tend to break things...)
440     get_filename_component(ha "${h}" ABSOLUTE)
441     if(EXISTS "${ha}")
442       # basename
443       get_filename_component(hb "${ha}" NAME)
444       # full path of the include wrapper
445       set(hl "${d}/${hb}")
446       # relative path of the header w.r.t the destination directory
447       file(RELATIVE_PATH CONFIG_HEADER_FILE "${d}" "${ha}")
448       if(NOT EXISTS "${hl}" OR "${ha}" IS_NEWER_THAN "${hl}")
449         file(WRITE "${hl}"
450 "/* THIS FILE WAS AUTOMATICALLY GENERATED BY ${PROJECT_NAME}.
451  * DO NOT EDIT! YOUR CHANGES WILL BE LOST!
453  * No include guards used, some headers need to be included
454  * multiple times (e.g. to #undef some helper macros).
455  */
456 #include \"${CONFIG_HEADER_FILE}\"
458       endif()
459     else()
460       message(SEND_ERROR "The file \"${ha}\" does not exist")
461     endif()
462   endforeach()
463 endfunction()
465 if(FOAM_HAS_FLEX_SOURCES)
466   # find flex for foam_check_and_compile_flex
467   find_package(FLEX REQUIRED)
468   include_directories(${FLEX_INCLUDE_DIRS})
469   set(FLEX_CXX_FLAGS "-+"
470     CACHE STRING "Flags used by the flex compiler for flex++ targets.")
471   mark_as_advanced(FLEX_CXX_FLAGS)
472 endif()
474 function(foam_check_and_compile_flex SRC_VAR)
475   if(${SRC_VAR} MATCHES "\\.L")
476     foreach(src ${${SRC_VAR}})
477       if(src MATCHES "\\.L$")
478         if(NOT FOAM_HAS_FLEX_SOURCES)
479           message(SEND_ERROR
480             "The list of source files contains flex++ sources"
481             "Set FOAM_HAS_FLEX_SOURCES to TRUE")
482         endif()
483         # construct .C name
484         get_filename_component(CXX_src "${src}" NAME)
485         string(REGEX REPLACE "\\.L$" ".C" CXX_src ${CXX_src})
486         set(CXX_src "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${CXX_src}")
487         # construct target name
488         get_filename_component(FLEX_target "${src}" NAME_WE)
489         set(FLEX_target "${FLEX_target}_Lexer")
490         # create flex target
491         flex_target(${FLEX_target}
492           "${CMAKE_CURRENT_SOURCE_DIR}/${src}" "${CXX_src}"
493           COMPILE_FLAGS ${FLEX_CXX_FLAGS}
494           )
495         # replace flex source with output of flex target
496         list(REMOVE_ITEM ${SRC_VAR} ${src})
497         list(APPEND ${SRC_VAR} ${CXX_src})
498       endif()
499     endforeach()
500     set(${SRC_VAR} "${${SRC_VAR}}" PARENT_SCOPE)
501   endif()
502 endfunction()
504 function(foam_link_loadable_library TARGET)
505   if(NOT WIN32)
506     if(FOAM_BUILD_FRAMEWORKS AND APPLE)
507       # make sure the target is a framework
508       get_target_property(_framework ${TARGET} FRAMEWORK)
509       if(NOT _framework)
510         message(FATAL_ERROR "The target ${TARGET} is not a FRAMEWORK")
511       endif()
512       # get the output location
513       get_target_property(_lib ${TARGET} LOCATION)
514       # link location and target for build tree
515       get_filename_component(_libname
516         "${_lib}${CMAKE_SHARED_LIBRARY_SUFFIX}" NAME)
517       set(_libname "${CMAKE_SHARED_LIBRARY_PREFIX}${_libname}")
518       set(_buildLink "${FOAM_LIBRARY_OUTPUT_DIRECTORY}/plugins/${_libname}")
519       file(RELATIVE_PATH _buildLinkTarget
520         "${FOAM_LIBRARY_OUTPUT_DIRECTORY}/plugins" "${_lib}")
521       # link target for install tree
522       file(RELATIVE_PATH _installLinkTarget
523         "${FOAM_FRAMEWORK_OUTPUT_DIRECTORY}" "${_lib}")
524       set(_installLinkTarget
525         "${FOAM_INSTALL_FRAMEWORK_PATH}/${_installLinkTarget}")
526     else()
527       # get the output location
528       get_target_property(_lib ${TARGET} LOCATION)
529       # link location and target for build tree
530       get_filename_component(_libname ${_lib} NAME)
531       set(_buildLink "${FOAM_LIBRARY_OUTPUT_DIRECTORY}/plugins/${_libname}")
532       file(RELATIVE_PATH _buildLinkTarget
533         "${FOAM_LIBRARY_OUTPUT_DIRECTORY}/plugins" "${_lib}")
534       # link target for install tree
535       file(RELATIVE_PATH _installLinkTarget
536         "${FOAM_INSTALL_PLUGIN_PATH}"
537         "${FOAM_INSTALL_LIBRARY_PATH}/${_libname}")
538       if(DEFINED FOAM_SOVERSION)
539         set(_installLinkTarget "${_installLinkTarget}.${FOAM_SOVERSION}")
540       endif()
541     endif()
542     # link location for install tree
543     set(_installLibDir
544       "${CMAKE_BINARY_DIR}/InstallFiles/lib/FreeFOAM-${FOAM_VERSION_FULL}")
545     set(_installLink "${_installLibDir}/plugins/${_libname}")
546     # create the links
547     file(MAKE_DIRECTORY "${_installLibDir}/plugins")
548     file(MAKE_DIRECTORY "${FOAM_LIBRARY_OUTPUT_DIRECTORY}/plugins")
549     add_custom_command(OUTPUT ${_buildLink} ${_installLink}
550       COMMAND "${CMAKE_COMMAND}" -E remove -f "${_buildLink}" "${_installLink}"
551       COMMAND "${CMAKE_COMMAND}" -E create_symlink
552         ${_buildLinkTarget} "${_buildLink}"
553       COMMAND "${CMAKE_COMMAND}" -E create_symlink
554         ${_installLinkTarget} "${_installLink}"
555       DEPENDS ${TARGET}
556       COMMENT "Creating plugin links for ${TARGET}"
557       VERBATIM)
559     # install the link
560     install(FILES ${_installLink}
561       DESTINATION ${FOAM_INSTALL_PLUGIN_PATH}
562       COMPONENT shlibs)
564     # make the custom command run...
565     add_custom_target(${TARGET}LoadableLinks ALL
566       DEPENDS ${_buildLink} ${_installLink})
567   endif()
568 endfunction()
571 # remove the list of documented apps from the cache
572 unset(__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets CACHE)
574 function(foam_add_executable_to_doc_index target source)
575   get_filename_component(f ${source} NAME_WE)
576   set(files "\"${f}_8C.html\" \"${f}_8C-source.html\"")
577   set(__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets
578     ${__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets} "${target} (${files})"
579     CACHE INTERNAL "Files to include in the documentation index"
580     )
581 endfunction()
583 function(foam_write_doc_index)
584   # construct the list of files
585   string(REPLACE ";"
586     ";\n    " tmp "    ${__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets}")
587   # get the version string right
588   string(LENGTH ${FOAM_VERSION_FULL} verlength)
589   set(verstr "                                                ")
590   math(EXPR verspacelength "48-${verlength}")
591   string(SUBSTRING "${verstr}" 0 ${verspacelength} verstr)
592   set(verstr "${FOAM_VERSION_FULL}${verstr}")
593   # write the doc index file
594   file(WRITE ${CMAKE_BINARY_DIR}/data/DoxyDocIndex.in
595 "/*--------------------------------*- C++ -*----------------------------------*\\
596 |               ______                _     ____          __  __              |
597 |              |  ____|             _| |_  / __ \\   /\\   |  \\/  |             |
598 |              | |__ _ __ ___  ___ /     \\| |  | | /  \\  | \\  / |             |
599 |              |  __| '__/ _ \\/ _ ( (| |) ) |  | |/ /\\ \\ | |\\/| |             |
600 |              | |  | | |  __/  __/\\_   _/| |__| / ____ \\| |  | |             |
601 |              |_|  |_|  \\___|\\___|  |_|   \\____/_/    \\_\\_|  |_|             |
602 |                                                                             |
603 |                   FreeFOAM: The Cross-Platform CFD Toolkit                  |
604 |                   Version:  ${verstr}|
605 |                   Web:      http://freefoam.sourceforge.net                 |
606 \\*---------------------------------------------------------------------------*/
607 FoamFile
609 version     2.0;
610 format      ascii;
611 class       dictionary;
612 object      docIndex;
614 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
616 docDir \"@FOAM_DOC_DIR@/Doxygen/html\";
618 docFiles {
619 ${tmp};
622 // ********************* vim: set ft=cpp sw=4 sts=4 et: ******************** //
624       )
625   # binary tree
626   set(FOAM_DOC_DIR "http://freefoam.sf.net/doc/${FOAM_VERSION_FULL}")
627   set(FOAM_LOCAL_DOC_DIR ${CMAKE_BINARY_DIR}/doc)
628   if(FOAM_USE_LOCAL_DOXYGEN_DOCS)
629     set(FOAM_DOC_DIR ${FOAM_LOCAL_DOC_DIR})
630   endif()
631   configure_file(${CMAKE_BINARY_DIR}/data/DoxyDocIndex.in
632     ${CMAKE_BINARY_DIR}/data/DoxyDocIndex @ONLY)
633   # install tree
634   set(FOAM_LOCAL_DOC_DIR ${FOAM_INSTALL_DOC_PATH})
635   if(FOAM_USE_LOCAL_DOXYGEN_DOCS)
636     set(FOAM_DOC_DIR ${FOAM_LOCAL_DOC_DIR})
637   endif()
638   configure_file(${CMAKE_BINARY_DIR}/data/DoxyDocIndex.in
639     ${CMAKE_BINARY_DIR}/InstallFiles/data/DoxyDocIndex @ONLY)
640 endfunction()
642 add_custom_target(doc ALL)
644 function(foam_create_manpage name source)
645   if(NOT FOAM_MANPAGE_FORMATS)
646     return()
647   endif()
648   foreach(format ${FOAM_MANPAGE_FORMATS})
649     # set up convenience targets and define output directory
650     if(format STREQUAL "manpage")
651       if(NOT TARGET doc-man)
652         add_custom_target(doc-man)
653         add_dependencies(doc doc-man)
654       endif()
655       set(man_page_dir "${CMAKE_BINARY_DIR}/doc/man/man")
656     elseif(format STREQUAL "xhtml")
657       if(NOT TARGET doc-html)
658         add_custom_target(doc-html)
659         add_dependencies(doc doc-html)
660       endif()
661       set(man_page_dir "${CMAKE_BINARY_DIR}/doc/html/man")
662     else()
663       message(FATAL_ERROR "ERROR: Unsupported manpage format '${format}'")
664     endif()
666     # construct the relative path to the source file
667     # and set up the section name
668     get_filename_component(f ${source} ABSOLUTE)
669     if(f MATCHES "\\.[0-9]+\\.in\\.txt$")
670       # if it is a AsciiDoc source, configure it
671       string(REGEX MATCH "\\.([0-9]+)\\.in\\.txt$" dummy ${f})
672       set(sect ${CMAKE_MATCH_1})
673       file(RELATIVE_PATH rel_f "${CMAKE_CURRENT_SOURCE_DIR}" "${f}")
674       string(REGEX REPLACE "\\.in\\.txt$" ".txt" source
675         "${CMAKE_CURRENT_BINARY_DIR}/${rel_f}")
676       configure_file("${f}" "${source}" @ONLY)
677     else()
678       set(sect "1")
679       set(source "${f}")
680     endif()
682     # create the output directory and construct the output name
683     file(MAKE_DIRECTORY "${man_page_dir}${sect}")
684     set(man_out "${man_page_dir}${sect}/${name}.${sect}")
685     if(format STREQUAL xhtml)
686       set(man_out "${man_out}.html")
687     endif()
689     # run through doxyToX
690     if(WIN32)
691       set(py_suffix .py)
692     else()
693       set(py_suffix)
694     endif()
695     add_custom_command(
696       OUTPUT "${man_out}"
697       COMMAND "${PYTHON_EXECUTABLE}"
698       "${CMAKE_BINARY_DIR}/data/utilities/doxyToX${py_suffix}"
699       -f ${format} -o "${man_page_dir}${sect}" "${name}" "${source}"
700       DEPENDS "${source}"
701       "${CMAKE_BINARY_DIR}/data/asciidoc/manpage.conf"
702       "${CMAKE_BINARY_DIR}/data/asciidoc/common.conf"
703       "${CMAKE_BINARY_DIR}/data/asciidoc/docbook.conf"
704       "${CMAKE_SOURCE_DIR}/data/utilities/doxyToX.py.in"
705       "${CMAKE_SOURCE_DIR}/data/python/FreeFOAM/doxyToAsciidoc.py"
706       ${ARGN}
707       WORKING_DIRECTORY "${man_page_dir}${sect}"
708       COMMENT "Creating ${format} help ${man_out}"
709       VERBATIM
710       )
712     # add convenience targets and install the files
713     add_custom_target(create_${format}_${name}_${sect}
714       DEPENDS ${man_out}
715       )
716     if(format STREQUAL manpage)
717       add_dependencies(doc-man create_${format}_${name}_${sect})
718       install(FILES ${man_out}
719         DESTINATION ${FOAM_INSTALL_MAN_PATH}/man${sect}
720         COMPONENT doc
721         )
722     else()
723       add_dependencies(doc-html create_${format}_${name}_${sect})
724       install(FILES ${man_out}
725         DESTINATION ${FOAM_INSTALL_DOC_PATH}/html/man${sect}
726         COMPONENT doc
727         )
728     endif()
729   endforeach()
730 endfunction()
733 function(foam_dependent_variables VAR)
734   # figure out a good cache name
735   set(cacheName "_FOAM_DEPENDENT_VARIABLES__${VAR}")
736   # if we're running the first time, initialise to the new value
737   if(NOT DEFINED ${cacheName})
738     set(${cacheName} "${${VAR}}")
739   endif()
740   # check for changes
741   if(NOT "${${cacheName}}" STREQUAL "${${VAR}}")
742     # if there are variables to purge, do so
743     foreach(var ${ARGN})
744       unset(${var})
745       unset(${var} CACHE)
746     endforeach()
747   endif()
748   # set the cache var to the old/new value
749   set(${cacheName} "${${VAR}}"
750     CACHE INTERNAL "FOAM_DEPENDENT_VARIABLES helper variable")
751 endfunction()
753 # helper function for FOAM_CONFIGURE_FILES
754 function(_set_config_files_variables installTree)
755   list(LENGTH FOAM_CONFIGURE_FILES_VARIABLES n)
756   math(EXPR n "${n} -1")
757   set(offset 1)
758   if(installTree)
759     set(offset 2)
760   endif()
761   foreach(i RANGE 0 ${n} 3)
762     math(EXPR j "${i}+${offset}")
763     list(GET FOAM_CONFIGURE_FILES_VARIABLES ${i} varname)
764     list(GET FOAM_CONFIGURE_FILES_VARIABLES ${j} varval)
765     set(${varname} "${varval}" PARENT_SCOPE)
766   endforeach()
767 endfunction()
769 function(foam_configure_files _config_files_installFilesVar)
770   # USE MANGLED NAMES to avoid collisions with user-variables
771   # in FOAM_CONFIGURE_FILES_VARIABLES.
772   #
773   # defaults
774   set(_config_files_destDir)
775   set(_config_files_basename FALSE)
776   set(_config_files_copyonly FALSE)
777   _foam_set_default(_config_files_strip_suffixes FOAM_STRIP_SUFFIXES "\\.in$")
778   set(_config_files_next_destdir FALSE)
779   set(_config_files_installFiles)
780   # 2-tuples of src;dst
781   set(_config_files_copyonly_files)
782   set(_config_files_buildtree_files)
783   set(_config_files_installtree_files)
784   # argument parsing
785   foreach(_config_files_a ${ARGN})
786     if(_config_files_next_destdir)
787       set(_config_files_destDir "${_config_files_a}")
788       set(_config_files_next_destdir FALSE)
789     elseif(_config_files_a STREQUAL COPYONLY)
790       set(_config_files_copyonly TRUE)
791       set(_config_files_basename FALSE)
792     elseif(_config_files_a STREQUAL DESTDIR)
793       set(_config_files_next_destdir TRUE)
794       set(_config_files_basename FALSE)
795     elseif(_config_files_a STREQUAL BASENAME)
796       set(_config_files_basename TRUE)
797     else()
798       # this is not an option, so it must be a file
799       # construct file names and sort into the lists
800       if(_config_files_a MATCHES "(.*)==(.*)")
801         set(_config_files_src "${CMAKE_MATCH_1}")
802         set(_config_files_dst_base "${CMAKE_MATCH_2}")
803       else()
804         set(_config_files_src "${_config_files_a}")
805         set(_config_files_dst_base "${_config_files_a}")
806       endif()
807       if(_config_files_basename)
808         get_filename_component(_config_files_dst_base
809           "${_config_files_dst_base}" NAME)
810       endif()
811       foreach(e ${_config_files_strip_suffixes})
812         if("${_config_files_dst_base}" MATCHES "${e}")
813           string(REGEX REPLACE "${e}" "" _config_files_dst_base "${_config_files_dst_base}")
814           break()
815         endif()
816       endforeach()
817       if(_config_files_destDir)
818         set(_config_files_dst_base
819           "${_config_files_destDir}/${_config_files_dst_base}")
820       endif()
821       set(_config_files_buildtree_name
822         "${CMAKE_BINARY_DIR}/${_config_files_dst_base}")
823       if(_config_files_copyonly)
824         list(APPEND _config_files_copyonly_files "${_config_files_src}"
825           "${_config_files_buildtree_name}")
826       else()
827         list(APPEND _config_files_buildtree_files "${_config_files_src}"
828           "${_config_files_buildtree_name}")
829         list(APPEND _config_files_installtree_files "${_config_files_src}"
830           "${CMAKE_BINARY_DIR}/InstallFiles/${_config_files_dst_base}")
831       endif()
832     endif()
833   endforeach()
834   # do COPYONLY files
835   set(_config_files_installFiles)
836   list(LENGTH _config_files_copyonly_files _config_files_ncopyonly)
837   math(EXPR _config_files_ncopyonly "${_config_files_ncopyonly} -1")
838   if(_config_files_ncopyonly GREATER 0)
839     foreach(_config_files_i RANGE 0 ${_config_files_ncopyonly} 2)
840       math(EXPR _config_files_j "${_config_files_i}+1")
841       list(GET _config_files_copyonly_files ${_config_files_i} _config_files_src)
842       list(GET _config_files_copyonly_files ${_config_files_j} _config_files_dst)
843       configure_file("${_config_files_src}" "${_config_files_dst}" COPYONLY)
844       list(APPEND _config_files_installFiles "${_config_files_dst}")
845     endforeach()
846   endif()
847   # do build-tree files
848   _set_config_files_variables(FALSE)
849   list(LENGTH _config_files_buildtree_files _config_files_nbuildtree)
850   math(EXPR _config_files_nbuildtree "${_config_files_nbuildtree} -1")
851   if(_config_files_nbuildtree GREATER 0)
852     foreach(_config_files_i RANGE 0 ${_config_files_nbuildtree} 2)
853       math(EXPR _config_files_j "${_config_files_i}+1")
854       list(GET _config_files_buildtree_files ${_config_files_i} _config_files_src)
855       list(GET _config_files_buildtree_files ${_config_files_j} _config_files_dst)
856       configure_file("${_config_files_src}" "${_config_files_dst}" @ONLY)
857     endforeach()
858   endif()
859   # do install-tree files
860   _set_config_files_variables(TRUE)
861   list(LENGTH _config_files_installtree_files _config_files_ninstalltree)
862   math(EXPR _config_files_ninstalltree "${_config_files_ninstalltree} -1")
863   if(_config_files_ninstalltree GREATER 0)
864     foreach(_config_files_i RANGE 0 ${_config_files_ninstalltree} 2)
865       math(EXPR _config_files_j "${_config_files_i}+1")
866       list(GET _config_files_installtree_files ${_config_files_i} _config_files_src)
867       list(GET _config_files_installtree_files ${_config_files_j} _config_files_dst)
868       configure_file("${_config_files_src}" "${_config_files_dst}" @ONLY)
869       list(APPEND _config_files_installFiles "${_config_files_dst}")
870     endforeach()
871   endif()
872   # return list of names in the install-tree
873   set(${_config_files_installFilesVar}
874     "${_config_files_installFiles}" PARENT_SCOPE)
875 endfunction()
877 function(foam_install_configured_files install_type)
878   if(NOT install_type MATCHES "^(FILES|PROGRAMS)$")
879     message(FATAL_ERROR "Expected FILES or PROGRAMS")
880   endif()
881   # argument parsing
882   foam_parse_arguments(_ficf "DESTINATION:1;COMPONENT:1" "" ${ARGN})
883   # sanity check
884   if(NOT _ficf_DEFAULT_ARGS)
885     message(FATAL_ERROR "At least one file required")
886   elseif(NOT _ficf_DESTINATION)
887     message(FATAL_ERROR "DESTINATION <dir> required")
888   endif()
889   if(_ficf_COMPONENT)
890     set(component COMPONENT ${_ficf_COMPONENT})
891   else()
892     set(component)
893   endif()
894   # process files
895   foreach(f ${_ficf_DEFAULT_ARGS})
896     # get subdirectory under InstallFiles
897     file(RELATIVE_PATH rf "${CMAKE_BINARY_DIR}/InstallFiles" "${f}")
898     # is it really a subdirectory?
899     if(rf MATCHES "^\\.\\.")
900       file(RELATIVE_PATH rf "${CMAKE_BINARY_DIR}" "${f}")
901       if(rf MATCHES "^\\.\\.")
902         message(FATAL_ERROR
903           "${f} not in a subdirectory of ${CMAKE_BINARY_DIR}/InstallFiles or ${CMAKE_BINARY_DIR}")
904       endif()
905     endif()
906     get_filename_component(p "${rf}" PATH)
907     # do it
908     install(${install_type} "${f}"
909       DESTINATION "${_ficf_DESTINATION}/${p}"
910       ${component}
911       )
912   endforeach()
913 endfunction()
915 function(foam_generate_doxygen)
916   set(doxyfilters)
917   set(noneVar "None")
918   foreach(type LIBRARY EXECUTABLE)
919     if(type STREQUAL LIBRARY)
920       get_property(FOAM_DOXYGEN_TARGETS GLOBAL PROPERTY FOAM_DOXYGEN_LIBRARIES)
921       set(var nameVar)
922     else()
923       get_property(FOAM_DOXYGEN_TARGETS GLOBAL PROPERTY FOAM_DOXYGEN_EXECUTABLES)
924       set(var noneVar)
925     endif()
926     foreach(name ${FOAM_DOXYGEN_TARGETS})
927       get_property(target_dir GLOBAL PROPERTY FOAM_DOXYGEN_${name}_${type}_DIR)
928       set(nameVar "'${name}'")
929       set(doxyfilters
930         "${doxyfilters}'${target_dir}/.*': ${${var}},\n")
931     endforeach()
932   endforeach()
933   set(doxyfilters "${doxyfilters}" PARENT_SCOPE)
934 endfunction()
936 function(foam_create_app_brief name section source)
937   set_property(GLOBAL APPEND PROPERTY FOAM_APP_BRIEF_${section}_APPS ${name})
938   if(NOT IS_ABSOLUTE "${source}")
939     set(source "${CMAKE_CURRENT_SOURCE_DIR}/${source}")
940   endif()
941   set_property(GLOBAL PROPERTY FOAM_APP_BRIEF_${name}_SOURCE "${source}")
942 endfunction()
944 function(foam_add_app_section name string)
945   set_property(GLOBAL APPEND PROPERTY FOAM_APP_BRIEF_SECTIONS ${name})
946   set_property(GLOBAL PROPERTY FOAM_APP_BRIEF_${name}_SECTION_STRING
947     "${string}")
948 endfunction()
950 function(foam_extract_brief_docs outfile)
951   if(NOT FOAM_MANPAGE_FORMATS)
952     return()
953   endif()
954   if(WIN32)
955     set(py_suffix .py)
956   else()
957     set(py_suffix)
958   endif()
959   if(NOT IS_ABSOLUTE ${outfile})
960     set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
961   endif()
962   get_property(sections GLOBAL PROPERTY FOAM_APP_BRIEF_SECTIONS)
963   set(sources)
964   set(FOAM_CONFIGURABLE_CONTENT "set(FOAM_CONFIGURABLE_CONTENT)")
965   foreach(section IN LISTS sections)
966     get_property(section_string GLOBAL PROPERTY
967       FOAM_APP_BRIEF_${section}_SECTION_STRING)
968     # write section string
969     set(FOAM_CONFIGURABLE_CONTENT "${FOAM_CONFIGURABLE_CONTENT}
970 set(FOAM_CONFIGURABLE_CONTENT \"\${FOAM_CONFIGURABLE_CONTENT}
971 ${section_string}\n\")
973     # iterate over apps in section
974     get_property(apps GLOBAL PROPERTY FOAM_APP_BRIEF_${section}_APPS)
975     foreach(app IN LISTS apps)
976       get_property(source GLOBAL PROPERTY FOAM_APP_BRIEF_${app}_SOURCE)
977       list(APPEND sources ${source})
978       set(FOAM_CONFIGURABLE_CONTENT "${FOAM_CONFIGURABLE_CONTENT}\n
979 set(source \"${source}\")
980 execute_process(
981   COMMAND \"${PYTHON_EXECUTABLE}\"
982   \"${CMAKE_BINARY_DIR}/data/utilities/extractBrief${py_suffix}\"
983   \"${FOAM_EXE_PREFIX}${app}\" \"\${source}\"
984   WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\"
985   RESULT_VARIABLE result
986   OUTPUT_VARIABLE brief
987   ERROR_VARIABLE brief
988   OUTPUT_STRIP_TRAILING_WHITESPACE)
989 if(NOT result)
990   set(FOAM_CONFIGURABLE_CONTENT \"\${FOAM_CONFIGURABLE_CONTENT}\${brief}\\n\")
991 else()
992   message(FATAL_ERROR \"Running extractBrief on '\${source}' failed:\\n\${brief}\")
993 endif()")
994     endforeach()
995   endforeach()
996   set(FOAM_CONFIGURABLE_CONTENT "${FOAM_CONFIGURABLE_CONTENT}
997 configure_file(\"${CMAKE_SOURCE_DIR}/CMake/FOAMConfigurableFile.in\"
998   \"${outfile}\" @ONLY)")
999   configure_file(${CMAKE_SOURCE_DIR}/CMake/FOAMConfigurableFile.in
1000     ${CMAKE_CURRENT_BINARY_DIR}/ExtractBriefDocs.cmake @ONLY)
1001   add_custom_command(OUTPUT "${outfile}"
1002     COMMAND "${CMAKE_COMMAND}"
1003       -P ${CMAKE_CURRENT_BINARY_DIR}/ExtractBriefDocs.cmake
1004     DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ExtractBriefDocs.cmake ${sources}
1005     COMMENT "Extracting brief application descriptions"
1006     VERBATIM)
1007 endfunction()
1009 function(foam_compile_asy outvar formats)
1010   if(NOT ASY_EXECUTABLE)
1011     message(SEND_ERROR "ASY_EXECUTABLE must be set")
1012   endif()
1013   set(output)
1014   foreach(f IN LISTS ARGN)
1015     if(IS_ABSOLUTE "${f}")
1016       file(RELATIVE_PATH f "${CMAKE_CURRENT_SOURCE_DIR}" "${f}")
1017     endif()
1018     get_filename_component(d "${f}" PATH)
1019     get_filename_component(ff "${f}" NAME_WE)
1020     string(REPLACE ".asy" "" o "${f}")
1021     configure_file("${f}" "${CMAKE_CURRENT_BINARY_DIR}/${f}" COPYONLY)
1022     foreach(fmt IN LISTS formats)
1023       list(APPEND output "${CMAKE_CURRENT_BINARY_DIR}/${o}.${fmt}")
1024       add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${o}.${fmt}"
1025         COMMAND "${ASY_EXECUTABLE}" -f${fmt} -tex pdflatex "${ff}"
1026         DEPENDS ${f}
1027         WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${d}"
1028         COMMENT "Creating Asymptote graphics ${o}.${fmt}"
1029         VERBATIM)
1030     endforeach()
1031   endforeach()
1032   set(${outvar} "${output}" PARENT_SCOPE)
1033 endfunction()
1035 function(foam_fix_apple_gcc_bug)
1036   if(APPLE AND CMAKE_COMPILER_IS_GNUCXX AND NOT DEFINED _FOAM_APPLE_GCC_BUGFIX)
1037     set(_FOAM_APPLE_GCC_BUGFIX TRUE CACHE INTERNAL "Apple GCC bug checked")
1038     execute_process(COMMAND "${CMAKE_CXX_COMPILER}" --version
1039       OUTPUT_VARIABLE output
1040       ERROR_VARIABLE  output
1041       )
1042     if(output MATCHES "4\\.2\\.1 \\(Apple Inc\\.")
1043       # only override if not changed by user
1044       if(CMAKE_CXX_FLAGS_RELEASE STREQUAL "${CMAKE_CXX_FLAGS_RELEASE_INIT}")
1045         message(WARNING
1046           "Apple GCC-4.2.1 detected\n"
1047           "Replacing -O3 by -O2 in CMAKE_CXX_FLAGS_RELEASE")
1048         string(REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE
1049           "${CMAKE_CXX_FLAGS_RELEASE}")
1050         set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING
1051           "Flags used by the compiler during release builds" FORCE)
1052         set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" PARENT_SCOPE)
1053       endif()
1054     endif()
1055   endif()
1056 endfunction()
1058 endif()
1060 # ------------------------- vim: set sw=2 sts=2 et: --------------- end-of-file