FIX: Invalid HTML in FoamHeader.html.in
[freefoam.git] / CMake / FOAMWmakeCompatibility.cmake.in
blobfae2e73038b8c46c7407ea2b1dd5489648cf122d
1 # - Wmake compatibility module
3 #  FOAM_ADD_WMAKE_TARGET([<target-var> [<dir>]])
5 # Create a target that is described by the OpenFOAM wmake build system. The
6 # function parses the files <dir>/Make/files and <dir>/Make/options and then
7 # creates an executable or a library. The name of the target will be returned
8 # in <target-var> and <dir> defaults to CMAKE_CURRENT_SOURCE_DIR. If the target
9 # name ends on "Foam" (but not "ToFoam"), this suffix will be stripped. The
10 # parsing is quite rudimentary, especially variable substitution might fail and
11 # the include-directories detection is not very robust at the moment. Consider
12 # this function to be very experimental. Comments and patches are welcome.
15 #-------------------------------------------------------------------------------
16 #               ______                _     ____          __  __
17 #              |  ____|             _| |_  / __ \   /\   |  \/  |
18 #              | |__ _ __ ___  ___ /     \| |  | | /  \  | \  / |
19 #              |  __| '__/ _ \/ _ ( (| |) ) |  | |/ /\ \ | |\/| |
20 #              | |  | | |  __/  __/\_   _/| |__| / ____ \| |  | |
21 #              |_|  |_|  \___|\___|  |_|   \____/_/    \_\_|  |_|
23 #                   FreeFOAM: The Cross-Platform CFD Toolkit
25 # Copyright (C) 2008-2011 Michael Wild <themiwi@users.sf.net>
26 #                         Gerber van der Graaf <gerber_graaf@users.sf.net>
27 #-------------------------------------------------------------------------------
28 # License
29 #   This file is part of FreeFOAM.
31 #   FreeFOAM is free software; you can redistribute it and/or modify it
32 #   under the terms of the GNU General Public License as published by the
33 #   Free Software Foundation; either version 2 of the License, or (at your
34 #   option) any later version.
36 #   FreeFOAM is distributed in the hope that it will be useful, but WITHOUT
37 #   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38 #   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
39 #   for more details.
41 #   You should have received a copy of the GNU General Public License
42 #   along with FreeFOAM; if not, write to the Free Software Foundation,
43 #   Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
45 # Description
46 #   Wmake compatibility module
48 #-------------------------------------------------------------------------------
50 # this requires cpp
51 find_program(CPP_EXECUTABLE cpp)
52 mark_as_advanced(CPP_EXECUTABLE)
53 if(NOT CPP_EXECUTABLE)
54   message(SEND_ERROR "Required program 'cpp' not found")
55 endif()
57 if(PROJECT_NAME)
58   set(proptype_tmpl "DIRECTORY;\${dir}")
59 else()
60   set(proptype GLOBAL)
61 endif()
63 # Run <filename> through the preprocessor and return
64 # the results in <var>.
65 function(_foam_awt_preprocess var filename)
66   set(defs -D@FOAM_OS@)
67   if(FOAM_DOUBLE_PRECISION OR FOAM_DEFINITIONS MATCHES -DDP)
68     list(APPEND defs -DDP)
69   else()
70     list(APPEND defs -DSP)
71   endif()
72   execute_process(
73     COMMAND "${CPP_EXECUTABLE}" -xc ${defs} -P -E ${filename}
74     RESULT_VARIABLE res
75     OUTPUT_VARIABLE out
76     ERROR_VARIABLE err
77     )
78   if(res)
79     message(SEND_ERROR "Preprocessing of ${filename} failed with:\n${err}")
80   endif()
81   # wrap line continuations
82   string(REGEX REPLACE "\\\\n" " " out "${out}")
83   # strip leading/trailing space and empty lines
84   string(STRIP "${out}" out)
85   string(REGEX REPLACE "\n\n+" "\n" out "${out}")
86   set(${var} "${out}" PARENT_SCOPE)
87 endfunction()
89 # Parse the variable definitions in <str> and store the names in
90 # the FOAM_AWT_VARIABLES property of <dir> and the values in
91 # FOAM_AWT_VALUE_<varname>. The definitions are removed from the
92 # string and the result is returned in <outvar>
93 function(_foam_awt_collect_vars outvar dir str)
94   if(PROJECT_NAME)
95     string(CONFIGURE "${proptype_tmpl}" proptype)
96   endif()
97   # initialize well known variables
98   foreach(var FOAM_APPBIN FOAM_LIBBIN FOAM_SOLVERS FOAM_SRC FOAM_USER_APPBIN
99       FOAM_USER_LIBBIN LIB_SRC)
100     set_property(${proptype} APPEND PROPERTY FOAM_AWT_VARIABLES ${var})
101     set_property(${proptype} PROPERTY FOAM_AWT_VALUE_${var} "${var}")
102   endforeach()
103   string(REPLACE "\n" ";" lines "${str}")
104   foreach(l ${lines})
105     if(l MATCHES "^[ \t]*([^ \t]+)[ \t]*=[ \t]*([^ \t].*)")
106       set_property(${proptype} APPEND PROPERTY FOAM_AWT_VARIABLES ${CMAKE_MATCH_1})
107       string(STRIP "${CMAKE_MATCH_2}" val)
108       set_property(${proptype} PROPERTY FOAM_AWT_VALUE_${CMAKE_MATCH_1} "${val}")
109       list(REMOVE_ITEM lines "${l}")
110     endif()
111   endforeach()
112   string(REPLACE ";" "\n" lines "${lines}")
113   set(${outvar} "${lines}" PARENT_SCOPE)
114 endfunction()
116 # Convenience function to retrieve the value of the FOAM_AWT_VALUE_<name>
117 # property of <dir> in <outvar>.
118 function(_foam_awt_get_value outvar dir name)
119   if(PROJECT_NAME)
120     string(CONFIGURE "${proptype_tmpl}" proptype)
121   endif()
122   get_property(variables ${proptype} PROPERTY FOAM_AWT_VARIABLES)
123   list(FIND variables ${name} idx)
124   if(idx LESS 0)
125     message(FATAL_ERROR "Failed to resolve variable ${name}")
126   endif()
127   get_property(val ${proptype} PROPERTY FOAM_AWT_VALUE_${name})
128   set(${outvar} "${val}" PARENT_SCOPE)
129 endfunction()
131 # Try to resolve all $(name) variable references in <str> using the variables
132 # stored in the directory properties of <dir> and return the resulting string
133 # in <outvar>.
134 function(_foam_awt_resolve_vars outvar dir str)
135   if(PROJECT_NAME)
136     string(CONFIGURE "${proptype_tmpl}" proptype)
137   endif()
138   # resolve itself
139   get_property(variables ${proptype} PROPERTY FOAM_AWT_VARIABLES)
140   foreach(var ${variables})
141     get_property(val ${proptype} PROPERTY FOAM_AWT_VALUE_${var})
142     while(val MATCHES "\\$\\(([^ \t)]+)\\)")
143       set(ref ${CMAKE_MATCH_1})
144       _foam_awt_get_value(refval "${dir}" ${ref})
145       string(REGEX REPLACE "\\$\\(${ref}\\)" "${refval}" val "${val}")
146     endwhile()
147     set_property(${proptype} PROPERTY FOAM_AWT_VALUE_${var} "${val}")
148   endforeach()
149   # now resolve str
150   while(str MATCHES "\\$\\(([^ \t)]+)\\)")
151     set(ref ${CMAKE_MATCH_1})
152     _foam_awt_get_value(refval "${dir}" ${ref})
153     string(REGEX REPLACE "\\$\\(${ref}\\)" "${refval}" str "${str}")
154   endwhile()
155   set(${outvar} "${str}" PARENT_SCOPE)
156 endfunction()
158 # Determines whether <lib> is a library built by @PROJECT_NAME@
159 function(_foam_awt_is_foam_library outvar lib)
160   set(result FALSE)
161   if(PROJECT_NAME)
162     if(TARGET FOAM_${lib})
163       set(result TRUE)
164     endif()
165   else()
166     if(EXISTS
167         "@FOAM_LIB_DIR@/@CMAKE_SHARED_LIBRARY_PREFIX@${lib}@CMAKE_SHARED_LIBRARY_SUFFIX@"
168         OR EXISTS
169         "@FOAM_LIB_DIR@/@CMAKE_SHARED_LIBRARY_PREFIX@${lib}@CMAKE_SHARED_MODULE_SUFFIX@"
170         )
171       set(result TRUE)
172     endif()
173   endif()
174   set(${outvar} ${result} PARENT_SCOPE)
175 endfunction()
177 # Parse <dir>/Make/files and <dir>/Make/options and return the target type in
178 # <typevar> (either LIB or EXE if it is a library or executable, respectively),
179 # the target name in <targetvar>, the list of source files in <filesvar>, the
180 # link libraries in <libsvar> and the include directories in <incdirsvar>.
181 function(_foam_awt_parse typevar targetvar filesvar libsvar incdirsvar dir)
182   if(PROJECT_NAME)
183     string(CONFIGURE "${proptype_tmpl}" proptype)
184   endif()
185   set(f_files "${dir}/Make/files")
186   set(f_options "${dir}/Make/options")
187   foreach(f f_files f_options)
188     if(NOT EXISTS "${${f}}")
189       message(SEND_ERROR "The file '${${f}}' does not exist")
190     endif()
191   endforeach()
192   _foam_awt_preprocess(l_files "${f_files}")
193   _foam_awt_preprocess(l_options "${f_options}")
194   set(lines "${l_files}\n${l_options}")
195   _foam_awt_collect_vars(lines "${dir}" "${lines}")
196   _foam_awt_resolve_vars(lines "${dir}" "${lines}")
197   string(REPLACE "\n" ";" lines "${lines}")
198   set(files ${f_files} ${f_options})
199   if(PROJECT_NAME)
200     set_source_files_properties(${files} PROPERTIES HEADER_FILE_ONLY TRUE)
201   endif()
202   foreach(f ${lines})
203     string(STRIP "${f}" f)
204     # this presumably is a file
205     if(NOT IS_ABSOLUTE ${f})
206       set(f "${dir}/${f}")
207     endif()
208     if(EXISTS "${f}")
209       list(APPEND files "${f}")
210     else()
211       message("WARNING: No such file '${f}'")
212     endif()
213   endforeach()
214   get_property(lib_name ${proptype} PROPERTY FOAM_AWT_VALUE_LIB)
215   get_property(exe_name ${proptype} PROPERTY FOAM_AWT_VALUE_EXE)
216   if(exe_name)
217     set(type EXE)
218     set(target ${exe_name})
219   elseif(lib_name)
220     set(type LIB)
221     set(target ${lib_name})
222   else()
223     message(FATAL_ERROR "ERROR: '${f_files}'\n"
224       "does neither contain a definition for EXE or LIB")
225   endif()
226   get_filename_component(target "${target}" NAME_WE)
227   # get link libraries
228   get_property(libs_str ${proptype} PROPERTY FOAM_AWT_VALUE_${type}_LIBS)
229   separate_arguments(libs_str)
230   set(libs)
231   foreach(l ${libs_str})
232     string(STRIP "${l}" l)
233     string(REGEX REPLACE "^-l" "" l "${l}")
234     _foam_awt_is_foam_library(is_foam_lib ${l})
235     if(is_foam_lib)
236       set(l FOAM_${l})
237     endif()
238     list(APPEND libs ${l})
239   endforeach()
240   # get include directories
241   get_property(incdirs_str ${proptype} PROPERTY FOAM_AWT_VALUE_EXE_INC)
242   separate_arguments(incdirs_str)
243   set(incdirs)
244   foreach(dd ${incdirs_str})
245     set(d "${dd}")
246     if(d MATCHES "lnInclude$")
247       get_filename_component(d "${d}" PATH)
248     endif()
249     get_filename_component(d "${d}" NAME)
250     set(d "@FOAM_INCLUDE_DIR@/${d}")
251     if(IS_DIRECTORY "${d}")
252       list(APPEND incdirs "${d}")
253     else()
254       message("WARNING: Don't know how to translate include-directory '${dd}'")
255     endif()
256   endforeach()
257   # return arguments to caller
258   set(${typevar} ${type} PARENT_SCOPE)
259   set(${targetvar} ${target} PARENT_SCOPE)
260   set(${filesvar} "${files}" PARENT_SCOPE)
261   set(${libsvar} "${libs}" PARENT_SCOPE)
262   set(${incdirsvar} "${incdirs}" PARENT_SCOPE)
263 endfunction()
265 function(foam_add_wmake_target)
266   if(ARGV0)
267     set(outvar ${ARGV0})
268   else()
269     set(outvar)
270   endif()
271   if(ARGV1)
272     set(dir "${ARGV1}")
273   else()
274     set(dir "${CMAKE_CURRENT_SOURCE_DIR}")
275   endif()
276   _foam_awt_parse(type target files libs incdirs "${dir}")
277   if(incdirs)
278     include_directories(${incdirs})
279   endif()
280   if(type STREQUAL EXE)
281     # try to be smart about the executable name
282     if(NOT target MATCHES "ToFoam$"AND target MATCHES "(.*)Foam$" )
283       set(target ${CMAKE_MATCH_1})
284     endif()
285     foam_add_executable(${target} ${files})
286   elseif(type STREQUAL LIB)
287     foam_add_library(${target} ${files})
288   endif()
289   target_link_libraries(${target} ${libs})
290   if(outvar)
291     set(${outvar} ${target} PARENT_SCOPE)
292   endif()
293 endfunction()
295 # ------------------------- vim: set sw=2 sts=2 et: --------------- end-of-file