ENH: Set VERSION and SOVERSION properties on libraries
[freefoam.git] / CMake / FOAMUtilities.cmake
blob3e040598b6a37082da1125bdb36ccaffbe0c2eb9
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(FOAM_BUILD_FRAMEWORKS AND APPLE)
506     # make sure the target is a framework
507     get_target_property(_framework ${TARGET} FRAMEWORK)
508     if(NOT _framework)
509       message(FATAL_ERROR "The target ${TARGET} is not a FRAMEWORK")
510     endif()
511     # get the output location
512     get_target_property(_lib ${TARGET} LOCATION)
513     # construct link-name
514     get_filename_component(_libname ${_lib} NAME)
515     set(_libname "${CMAKE_SHARED_LIBRARY_PREFIX}${_libname}${CMAKE_SHARED_LIBRARY_SUFFIX}")
516     # full link path in build tree
517     set(_buildLink ${FOAM_LIBRARY_OUTPUT_DIRECTORY}/${_libname})
518     # full link path in InstallFiles
519     file(RELATIVE_PATH _installLinkTarget ${FOAM_FRAMEWORK_OUTPUT_DIRECTORY} ${_lib})
520     set(_installLinkTarget ${FOAM_INSTALL_FRAMEWORK_PATH}/${_installLinkTarget})
521     set(_installLink ${CMAKE_BINARY_DIR}/InstallFiles/lib/FreeFOAM-${FOAM_VERSION_FULL}/${_libname})
523     # create the links
524     file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/InstallFiles/lib/FreeFOAM-${FOAM_VERSION_FULL})
525     add_custom_command(OUTPUT ${_buildLink} ${_installLink}
526       COMMAND "${CMAKE_COMMAND}" -E remove -f ${_buildLink} ${_installLink}
527       COMMAND ln -s ${_lib} ${_buildLink}
528       COMMAND ln -s ${_installLinkTarget} ${_installLink}
529       DEPENDS ${TARGET}
530       COMMENT "Creating symbolic links for ${TARGET}"
531       VERBATIM
532       )
534     # install the link
535     install(FILES ${_installLink}
536       DESTINATION ${FOAM_INSTALL_LIBRARY_PATH}
537       COMPONENT shlibs
538       )
540     # make the custom command run...
541     add_custom_target(${TARGET}LoadableLinks ALL
542       DEPENDS ${_buildLink} ${_installLink}
543       )
544   endif()
545 endfunction()
548 # remove the list of documented apps from the cache
549 unset(__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets CACHE)
551 function(foam_add_executable_to_doc_index target source)
552   get_filename_component(f ${source} NAME_WE)
553   set(files "\"${f}_8C.html\" \"${f}_8C-source.html\"")
554   set(__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets
555     ${__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets} "${target} (${files})"
556     CACHE INTERNAL "Files to include in the documentation index"
557     )
558 endfunction()
560 function(foam_write_doc_index)
561   # construct the list of files
562   string(REPLACE ";"
563     ";\n    " tmp "    ${__FOAM_ADD_EXECUTABLE_TO_DOC_INDEX_targets}")
564   # get the version string right
565   string(LENGTH ${FOAM_VERSION_FULL} verlength)
566   set(verstr "                                                ")
567   math(EXPR verspacelength "48-${verlength}")
568   string(SUBSTRING "${verstr}" 0 ${verspacelength} verstr)
569   set(verstr "${FOAM_VERSION_FULL}${verstr}")
570   # write the doc index file
571   file(WRITE ${CMAKE_BINARY_DIR}/data/DoxyDocIndex.in
572 "/*--------------------------------*- C++ -*----------------------------------*\\
573 |               ______                _     ____          __  __              |
574 |              |  ____|             _| |_  / __ \\   /\\   |  \\/  |             |
575 |              | |__ _ __ ___  ___ /     \\| |  | | /  \\  | \\  / |             |
576 |              |  __| '__/ _ \\/ _ ( (| |) ) |  | |/ /\\ \\ | |\\/| |             |
577 |              | |  | | |  __/  __/\\_   _/| |__| / ____ \\| |  | |             |
578 |              |_|  |_|  \\___|\\___|  |_|   \\____/_/    \\_\\_|  |_|             |
579 |                                                                             |
580 |                   FreeFOAM: The Cross-Platform CFD Toolkit                  |
581 |                   Version:  ${verstr}|
582 |                   Web:      http://freefoam.sourceforge.net                 |
583 \\*---------------------------------------------------------------------------*/
584 FoamFile
586 version     2.0;
587 format      ascii;
588 class       dictionary;
589 object      docIndex;
591 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
593 docDir \"@FOAM_DOC_DIR@/Doxygen/html\";
595 docFiles {
596 ${tmp};
599 // ********************* vim: set ft=cpp sw=4 sts=4 et: ******************** //
601       )
602   # binary tree
603   set(FOAM_DOC_DIR "http://freefoam.sf.net/doc/${FOAM_VERSION_FULL}")
604   set(FOAM_LOCAL_DOC_DIR ${CMAKE_BINARY_DIR}/doc)
605   if(FOAM_USE_LOCAL_DOXYGEN_DOCS)
606     set(FOAM_DOC_DIR ${FOAM_LOCAL_DOC_DIR})
607   endif()
608   configure_file(${CMAKE_BINARY_DIR}/data/DoxyDocIndex.in
609     ${CMAKE_BINARY_DIR}/data/DoxyDocIndex @ONLY)
610   # install tree
611   set(FOAM_LOCAL_DOC_DIR ${FOAM_INSTALL_DOC_PATH})
612   if(FOAM_USE_LOCAL_DOXYGEN_DOCS)
613     set(FOAM_DOC_DIR ${FOAM_LOCAL_DOC_DIR})
614   endif()
615   configure_file(${CMAKE_BINARY_DIR}/data/DoxyDocIndex.in
616     ${CMAKE_BINARY_DIR}/InstallFiles/data/DoxyDocIndex @ONLY)
617 endfunction()
619 add_custom_target(doc ALL)
621 function(foam_create_manpage name source)
622   if(NOT FOAM_MANPAGE_FORMATS)
623     return()
624   endif()
625   foreach(format ${FOAM_MANPAGE_FORMATS})
626     # set up convenience targets and define output directory
627     if(format STREQUAL "manpage")
628       if(NOT TARGET doc-man)
629         add_custom_target(doc-man)
630         add_dependencies(doc doc-man)
631       endif()
632       set(man_page_dir "${CMAKE_BINARY_DIR}/doc/man/man")
633     elseif(format STREQUAL "xhtml")
634       if(NOT TARGET doc-html)
635         add_custom_target(doc-html)
636         add_dependencies(doc doc-html)
637       endif()
638       set(man_page_dir "${CMAKE_BINARY_DIR}/doc/html/man")
639     else()
640       message(FATAL_ERROR "ERROR: Unsupported manpage format '${format}'")
641     endif()
643     # construct the relative path to the source file
644     # and set up the section name
645     get_filename_component(f ${source} ABSOLUTE)
646     if(f MATCHES "\\.[0-9]+\\.in\\.txt$")
647       # if it is a AsciiDoc source, configure it
648       string(REGEX MATCH "\\.([0-9]+)\\.in\\.txt$" dummy ${f})
649       set(sect ${CMAKE_MATCH_1})
650       file(RELATIVE_PATH rel_f "${CMAKE_CURRENT_SOURCE_DIR}" "${f}")
651       string(REGEX REPLACE "\\.in\\.txt$" ".txt" source
652         "${CMAKE_CURRENT_BINARY_DIR}/${rel_f}")
653       configure_file("${f}" "${source}" @ONLY)
654     else()
655       set(sect "1")
656       set(source "${f}")
657     endif()
659     # create the output directory and construct the output name
660     file(MAKE_DIRECTORY "${man_page_dir}${sect}")
661     set(man_out "${man_page_dir}${sect}/${name}.${sect}")
662     if(format STREQUAL xhtml)
663       set(man_out "${man_out}.html")
664     endif()
666     # run through doxyToX
667     if(WIN32)
668       set(py_suffix .py)
669     else()
670       set(py_suffix)
671     endif()
672     add_custom_command(
673       OUTPUT "${man_out}"
674       COMMAND "${PYTHON_EXECUTABLE}"
675       "${CMAKE_BINARY_DIR}/data/utilities/doxyToX${py_suffix}"
676       -f ${format} -o "${man_page_dir}${sect}" "${name}" "${source}"
677       DEPENDS "${source}"
678       "${CMAKE_BINARY_DIR}/data/asciidoc/manpage.conf"
679       "${CMAKE_BINARY_DIR}/data/asciidoc/common.conf"
680       "${CMAKE_BINARY_DIR}/data/asciidoc/docbook.conf"
681       "${CMAKE_SOURCE_DIR}/data/utilities/doxyToX.py.in"
682       "${CMAKE_SOURCE_DIR}/data/python/FreeFOAM/doxyToAsciidoc.py"
683       ${ARGN}
684       WORKING_DIRECTORY "${man_page_dir}${sect}"
685       COMMENT "Creating ${format} help ${man_out}"
686       VERBATIM
687       )
689     # add convenience targets and install the files
690     add_custom_target(create_${format}_${name}_${sect}
691       DEPENDS ${man_out}
692       )
693     if(format STREQUAL manpage)
694       add_dependencies(doc-man create_${format}_${name}_${sect})
695       install(FILES ${man_out}
696         DESTINATION ${FOAM_INSTALL_MAN_PATH}/man${sect}
697         COMPONENT doc
698         )
699     else()
700       add_dependencies(doc-html create_${format}_${name}_${sect})
701       install(FILES ${man_out}
702         DESTINATION ${FOAM_INSTALL_DOC_PATH}/html/man${sect}
703         COMPONENT doc
704         )
705     endif()
706   endforeach()
707 endfunction()
710 function(foam_dependent_variables VAR)
711   # figure out a good cache name
712   set(cacheName "_FOAM_DEPENDENT_VARIABLES__${VAR}")
713   # if we're running the first time, initialise to the new value
714   if(NOT DEFINED ${cacheName})
715     set(${cacheName} "${${VAR}}")
716   endif()
717   # check for changes
718   if(NOT "${${cacheName}}" STREQUAL "${${VAR}}")
719     # if there are variables to purge, do so
720     foreach(var ${ARGN})
721       unset(${var})
722       unset(${var} CACHE)
723     endforeach()
724   endif()
725   # set the cache var to the old/new value
726   set(${cacheName} "${${VAR}}"
727     CACHE INTERNAL "FOAM_DEPENDENT_VARIABLES helper variable")
728 endfunction()
730 # helper function for FOAM_CONFIGURE_FILES
731 function(_set_config_files_variables installTree)
732   list(LENGTH FOAM_CONFIGURE_FILES_VARIABLES n)
733   math(EXPR n "${n} -1")
734   set(offset 1)
735   if(installTree)
736     set(offset 2)
737   endif()
738   foreach(i RANGE 0 ${n} 3)
739     math(EXPR j "${i}+${offset}")
740     list(GET FOAM_CONFIGURE_FILES_VARIABLES ${i} varname)
741     list(GET FOAM_CONFIGURE_FILES_VARIABLES ${j} varval)
742     set(${varname} "${varval}" PARENT_SCOPE)
743   endforeach()
744 endfunction()
746 function(foam_configure_files _config_files_installFilesVar)
747   # USE MANGLED NAMES to avoid collisions with user-variables
748   # in FOAM_CONFIGURE_FILES_VARIABLES.
749   #
750   # defaults
751   set(_config_files_destDir)
752   set(_config_files_basename FALSE)
753   set(_config_files_copyonly FALSE)
754   _foam_set_default(_config_files_strip_suffixes FOAM_STRIP_SUFFIXES "\\.in$")
755   set(_config_files_next_destdir FALSE)
756   set(_config_files_installFiles)
757   # 2-tuples of src;dst
758   set(_config_files_copyonly_files)
759   set(_config_files_buildtree_files)
760   set(_config_files_installtree_files)
761   # argument parsing
762   foreach(_config_files_a ${ARGN})
763     if(_config_files_next_destdir)
764       set(_config_files_destDir "${_config_files_a}")
765       set(_config_files_next_destdir FALSE)
766     elseif(_config_files_a STREQUAL COPYONLY)
767       set(_config_files_copyonly TRUE)
768       set(_config_files_basename FALSE)
769     elseif(_config_files_a STREQUAL DESTDIR)
770       set(_config_files_next_destdir TRUE)
771       set(_config_files_basename FALSE)
772     elseif(_config_files_a STREQUAL BASENAME)
773       set(_config_files_basename TRUE)
774     else()
775       # this is not an option, so it must be a file
776       # construct file names and sort into the lists
777       if(_config_files_a MATCHES "(.*)==(.*)")
778         set(_config_files_src "${CMAKE_MATCH_1}")
779         set(_config_files_dst_base "${CMAKE_MATCH_2}")
780       else()
781         set(_config_files_src "${_config_files_a}")
782         set(_config_files_dst_base "${_config_files_a}")
783       endif()
784       if(_config_files_basename)
785         get_filename_component(_config_files_dst_base
786           "${_config_files_dst_base}" NAME)
787       endif()
788       foreach(e ${_config_files_strip_suffixes})
789         if("${_config_files_dst_base}" MATCHES "${e}")
790           string(REGEX REPLACE "${e}" "" _config_files_dst_base "${_config_files_dst_base}")
791           break()
792         endif()
793       endforeach()
794       if(_config_files_destDir)
795         set(_config_files_dst_base
796           "${_config_files_destDir}/${_config_files_dst_base}")
797       endif()
798       set(_config_files_buildtree_name
799         "${CMAKE_BINARY_DIR}/${_config_files_dst_base}")
800       if(_config_files_copyonly)
801         list(APPEND _config_files_copyonly_files "${_config_files_src}"
802           "${_config_files_buildtree_name}")
803       else()
804         list(APPEND _config_files_buildtree_files "${_config_files_src}"
805           "${_config_files_buildtree_name}")
806         list(APPEND _config_files_installtree_files "${_config_files_src}"
807           "${CMAKE_BINARY_DIR}/InstallFiles/${_config_files_dst_base}")
808       endif()
809     endif()
810   endforeach()
811   # do COPYONLY files
812   set(_config_files_installFiles)
813   list(LENGTH _config_files_copyonly_files _config_files_ncopyonly)
814   math(EXPR _config_files_ncopyonly "${_config_files_ncopyonly} -1")
815   if(_config_files_ncopyonly GREATER 0)
816     foreach(_config_files_i RANGE 0 ${_config_files_ncopyonly} 2)
817       math(EXPR _config_files_j "${_config_files_i}+1")
818       list(GET _config_files_copyonly_files ${_config_files_i} _config_files_src)
819       list(GET _config_files_copyonly_files ${_config_files_j} _config_files_dst)
820       configure_file("${_config_files_src}" "${_config_files_dst}" COPYONLY)
821       list(APPEND _config_files_installFiles "${_config_files_dst}")
822     endforeach()
823   endif()
824   # do build-tree files
825   _set_config_files_variables(FALSE)
826   list(LENGTH _config_files_buildtree_files _config_files_nbuildtree)
827   math(EXPR _config_files_nbuildtree "${_config_files_nbuildtree} -1")
828   if(_config_files_nbuildtree GREATER 0)
829     foreach(_config_files_i RANGE 0 ${_config_files_nbuildtree} 2)
830       math(EXPR _config_files_j "${_config_files_i}+1")
831       list(GET _config_files_buildtree_files ${_config_files_i} _config_files_src)
832       list(GET _config_files_buildtree_files ${_config_files_j} _config_files_dst)
833       configure_file("${_config_files_src}" "${_config_files_dst}" @ONLY)
834     endforeach()
835   endif()
836   # do install-tree files
837   _set_config_files_variables(TRUE)
838   list(LENGTH _config_files_installtree_files _config_files_ninstalltree)
839   math(EXPR _config_files_ninstalltree "${_config_files_ninstalltree} -1")
840   if(_config_files_ninstalltree GREATER 0)
841     foreach(_config_files_i RANGE 0 ${_config_files_ninstalltree} 2)
842       math(EXPR _config_files_j "${_config_files_i}+1")
843       list(GET _config_files_installtree_files ${_config_files_i} _config_files_src)
844       list(GET _config_files_installtree_files ${_config_files_j} _config_files_dst)
845       configure_file("${_config_files_src}" "${_config_files_dst}" @ONLY)
846       list(APPEND _config_files_installFiles "${_config_files_dst}")
847     endforeach()
848   endif()
849   # return list of names in the install-tree
850   set(${_config_files_installFilesVar}
851     "${_config_files_installFiles}" PARENT_SCOPE)
852 endfunction()
854 function(foam_install_configured_files install_type)
855   if(NOT install_type MATCHES "^(FILES|PROGRAMS)$")
856     message(FATAL_ERROR "Expected FILES or PROGRAMS")
857   endif()
858   # argument parsing
859   foam_parse_arguments(_ficf "DESTINATION:1;COMPONENT:1" "" ${ARGN})
860   # sanity check
861   if(NOT _ficf_DEFAULT_ARGS)
862     message(FATAL_ERROR "At least one file required")
863   elseif(NOT _ficf_DESTINATION)
864     message(FATAL_ERROR "DESTINATION <dir> required")
865   endif()
866   if(_ficf_COMPONENT)
867     set(component COMPONENT ${_ficf_COMPONENT})
868   else()
869     set(component)
870   endif()
871   # process files
872   foreach(f ${_ficf_DEFAULT_ARGS})
873     # get subdirectory under InstallFiles
874     file(RELATIVE_PATH rf "${CMAKE_BINARY_DIR}/InstallFiles" "${f}")
875     # is it really a subdirectory?
876     if(rf MATCHES "^\\.\\.")
877       file(RELATIVE_PATH rf "${CMAKE_BINARY_DIR}" "${f}")
878       if(rf MATCHES "^\\.\\.")
879         message(FATAL_ERROR
880           "${f} not in a subdirectory of ${CMAKE_BINARY_DIR}/InstallFiles or ${CMAKE_BINARY_DIR}")
881       endif()
882     endif()
883     get_filename_component(p "${rf}" PATH)
884     # do it
885     install(${install_type} "${f}"
886       DESTINATION "${_ficf_DESTINATION}/${p}"
887       ${component}
888       )
889   endforeach()
890 endfunction()
892 function(foam_generate_doxygen)
893   set(doxyfilters)
894   set(noneVar "None")
895   foreach(type LIBRARY EXECUTABLE)
896     if(type STREQUAL LIBRARY)
897       get_property(FOAM_DOXYGEN_TARGETS GLOBAL PROPERTY FOAM_DOXYGEN_LIBRARIES)
898       set(var nameVar)
899     else()
900       get_property(FOAM_DOXYGEN_TARGETS GLOBAL PROPERTY FOAM_DOXYGEN_EXECUTABLES)
901       set(var noneVar)
902     endif()
903     foreach(name ${FOAM_DOXYGEN_TARGETS})
904       get_property(target_dir GLOBAL PROPERTY FOAM_DOXYGEN_${name}_${type}_DIR)
905       set(nameVar "'${name}'")
906       set(doxyfilters
907         "${doxyfilters}'${target_dir}/.*': ${${var}},\n")
908     endforeach()
909   endforeach()
910   set(doxyfilters "${doxyfilters}" PARENT_SCOPE)
911 endfunction()
913 function(foam_create_app_brief name section source)
914   set_property(GLOBAL APPEND PROPERTY FOAM_APP_BRIEF_${section}_APPS ${name})
915   if(NOT IS_ABSOLUTE "${source}")
916     set(source "${CMAKE_CURRENT_SOURCE_DIR}/${source}")
917   endif()
918   set_property(GLOBAL PROPERTY FOAM_APP_BRIEF_${name}_SOURCE "${source}")
919 endfunction()
921 function(foam_add_app_section name string)
922   set_property(GLOBAL APPEND PROPERTY FOAM_APP_BRIEF_SECTIONS ${name})
923   set_property(GLOBAL PROPERTY FOAM_APP_BRIEF_${name}_SECTION_STRING
924     "${string}")
925 endfunction()
927 function(foam_extract_brief_docs outfile)
928   if(NOT FOAM_MANPAGE_FORMATS)
929     return()
930   endif()
931   if(WIN32)
932     set(py_suffix .py)
933   else()
934     set(py_suffix)
935   endif()
936   if(NOT IS_ABSOLUTE ${outfile})
937     set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}")
938   endif()
939   get_property(sections GLOBAL PROPERTY FOAM_APP_BRIEF_SECTIONS)
940   set(sources)
941   set(FOAM_CONFIGURABLE_CONTENT "set(FOAM_CONFIGURABLE_CONTENT)")
942   foreach(section IN LISTS sections)
943     get_property(section_string GLOBAL PROPERTY
944       FOAM_APP_BRIEF_${section}_SECTION_STRING)
945     # write section string
946     set(FOAM_CONFIGURABLE_CONTENT "${FOAM_CONFIGURABLE_CONTENT}
947 set(FOAM_CONFIGURABLE_CONTENT \"\${FOAM_CONFIGURABLE_CONTENT}
948 ${section_string}\n\")
950     # iterate over apps in section
951     get_property(apps GLOBAL PROPERTY FOAM_APP_BRIEF_${section}_APPS)
952     foreach(app IN LISTS apps)
953       get_property(source GLOBAL PROPERTY FOAM_APP_BRIEF_${app}_SOURCE)
954       list(APPEND sources ${source})
955       set(FOAM_CONFIGURABLE_CONTENT "${FOAM_CONFIGURABLE_CONTENT}\n
956 set(source \"${source}\")
957 execute_process(
958   COMMAND \"${PYTHON_EXECUTABLE}\"
959   \"${CMAKE_BINARY_DIR}/data/utilities/extractBrief${py_suffix}\"
960   \"${FOAM_EXE_PREFIX}${app}\" \"\${source}\"
961   WORKING_DIRECTORY \"${CMAKE_CURRENT_SOURCE_DIR}\"
962   RESULT_VARIABLE result
963   OUTPUT_VARIABLE brief
964   ERROR_VARIABLE brief
965   OUTPUT_STRIP_TRAILING_WHITESPACE)
966 if(NOT result)
967   set(FOAM_CONFIGURABLE_CONTENT \"\${FOAM_CONFIGURABLE_CONTENT}\${brief}\\n\")
968 else()
969   message(FATAL_ERROR \"Running extractBrief on '\${source}' failed:\\n\${brief}\")
970 endif()")
971     endforeach()
972   endforeach()
973   set(FOAM_CONFIGURABLE_CONTENT "${FOAM_CONFIGURABLE_CONTENT}
974 configure_file(\"${CMAKE_SOURCE_DIR}/CMake/FOAMConfigurableFile.in\"
975   \"${outfile}\" @ONLY)")
976   configure_file(${CMAKE_SOURCE_DIR}/CMake/FOAMConfigurableFile.in
977     ${CMAKE_CURRENT_BINARY_DIR}/ExtractBriefDocs.cmake @ONLY)
978   add_custom_command(OUTPUT "${outfile}"
979     COMMAND "${CMAKE_COMMAND}"
980       -P ${CMAKE_CURRENT_BINARY_DIR}/ExtractBriefDocs.cmake
981     DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ExtractBriefDocs.cmake ${sources}
982     COMMENT "Extracting brief application descriptions"
983     VERBATIM)
984 endfunction()
986 function(foam_compile_asy outvar formats)
987   set(output)
988   foreach(f IN LISTS ARGN)
989     if(NOT ASY_EXECUTABLE)
990       message(SEND_ERROR "ASY_EXECUTABLE must be set")
991     endif()
992     get_filename_component(d "${f}" PATH)
993     get_filename_component(ff "${f}" NAME_WE)
994     string(REPLACE ".asy" "" o "${f}")
995     configure_file("${f}" "${CMAKE_CURRENT_BINARY_DIR}/${f}" COPYONLY)
996     foreach(fmt IN LISTS formats)
997       list(APPEND output "${CMAKE_CURRENT_BINARY_DIR}/${o}.${fmt}")
998       add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${o}.${fmt}"
999         COMMAND "${ASY_EXECUTABLE}" -f${fmt} -tex pdflatex "${ff}"
1000         DEPENDS ${f}
1001         WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${d}"
1002         COMMENT "Creating Asymptote graphics ${o}.${fmt}"
1003         VERBATIM)
1004     endforeach()
1005   endforeach()
1006   set(${outvar} "${output}" PARENT_SCOPE)
1007 endfunction()
1009 function(foam_fix_apple_gcc_bug)
1010   if(APPLE AND CMAKE_COMPILER_IS_GNUCXX AND NOT DEFINED _FOAM_APPLE_GCC_BUGFIX)
1011     set(_FOAM_APPLE_GCC_BUGFIX TRUE CACHE INTERNAL "Apple GCC bug checked")
1012     execute_process(COMMAND "${CMAKE_CXX_COMPILER}" --version
1013       OUTPUT_VARIABLE output
1014       ERROR_VARIABLE  output
1015       )
1016     if(output MATCHES "4\\.2\\.1 \\(Apple Inc\\.")
1017       # only override if not changed by user
1018       if(CMAKE_CXX_FLAGS_RELEASE STREQUAL "${CMAKE_CXX_FLAGS_RELEASE_INIT}")
1019         message(WARNING
1020           "Apple GCC-4.2.1 detected\n"
1021           "Replacing -O3 by -O2 in CMAKE_CXX_FLAGS_RELEASE")
1022         string(REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE
1023           "${CMAKE_CXX_FLAGS_RELEASE}")
1024         set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING
1025           "Flags used by the compiler during release builds" FORCE)
1026         set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" PARENT_SCOPE)
1027       endif()
1028     endif()
1029   endif()
1030 endfunction()
1032 endif()
1034 # ------------------------- vim: set sw=2 sts=2 et: --------------- end-of-file