[CMake] CMake does not support the dep files for implicit dependency
[WebKit-https.git] / Source / cmake / WebKitMacros.cmake
1 include(CMakeParseArguments)
2 include(ProcessorCount)
3 ProcessorCount(PROCESSOR_COUNT)
4
5 macro(WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS)
6     set(_file ${CMAKE_CURRENT_SOURCE_DIR}/Platform${PORT}.cmake)
7     if (EXISTS ${_file})
8         message(STATUS "Using platform-specific CMakeLists: ${_file}")
9         include(${_file})
10     else ()
11         message(STATUS "Platform-specific CMakeLists not found: ${_file}")
12     endif ()
13 endmacro()
14
15 # Append the given dependencies to the source file
16 macro(ADD_SOURCE_DEPENDENCIES _source _deps)
17     set(_tmp)
18     get_source_file_property(_tmp ${_source} OBJECT_DEPENDS)
19     if (NOT _tmp)
20         set(_tmp "")
21     endif ()
22
23     foreach (f ${_deps})
24         list(APPEND _tmp "${f}")
25     endforeach ()
26
27     set_source_files_properties(${_source} PROPERTIES OBJECT_DEPENDS "${_tmp}")
28 endmacro()
29
30 macro(ADD_PRECOMPILED_HEADER _header _cpp _source)
31     if (MSVC)
32         get_filename_component(PrecompiledBasename ${_cpp} NAME_WE)
33         file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_source}")
34         set(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${_source}/${PrecompiledBasename}.pch")
35         set(_sources ${${_source}})
36
37         set_source_files_properties(${_cpp}
38             PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\""
39             OBJECT_OUTPUTS "${PrecompiledBinary}")
40         set_source_files_properties(${_sources}
41             PROPERTIES COMPILE_FLAGS "/Yu\"${_header}\" /FI\"${_header}\" /Fp\"${PrecompiledBinary}\""
42             OBJECT_DEPENDS "${PrecompiledBinary}")
43         list(APPEND ${_source} ${_cpp})
44     endif ()
45     #FIXME: Add support for Xcode.
46 endmacro()
47
48 # Helper macro which wraps generate-bindings-all.pl script.
49 #   target is a new target name to be added
50 #   OUTPUT_SOURCE is a list name which will contain generated sources.(eg. WebCore_SOURCES)
51 #   INPUT_FILES are IDL files to generate.
52 #   BASE_DIR is base directory where script is called.
53 #   IDL_INCLUDES is value of --include argument. (eg. ${WEBCORE_DIR}/bindings/js)
54 #   FEATURES is a value of --defines argument.
55 #   DESTINATION is a value of --outputDir argument.
56 #   GENERATOR is a value of --generator argument.
57 #   SUPPLEMENTAL_DEPFILE is a value of --supplementalDependencyFile. (optional)
58 #   PP_EXTRA_OUTPUT is extra outputs of preprocess-idls.pl. (optional)
59 #   PP_EXTRA_ARGS is extra arguments for preprocess-idls.pl. (optional)
60 function(GENERATE_BINDINGS target)
61     set(options)
62     set(oneValueArgs OUTPUT_SOURCE BASE_DIR FEATURES DESTINATION GENERATOR SUPPLEMENTAL_DEPFILE)
63     set(multiValueArgs INPUT_FILES IDL_INCLUDES PP_EXTRA_OUTPUT PP_EXTRA_ARGS)
64     cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
65     set(binding_generator ${WEBCORE_DIR}/bindings/scripts/generate-bindings-all.pl)
66     set(idl_attributes_file ${WEBCORE_DIR}/bindings/scripts/IDLAttributes.txt)
67     set(idl_files_list ${CMAKE_CURRENT_BINARY_DIR}/idl_files_${target}.tmp)
68     set(_supplemental_dependency)
69
70     set(content)
71     foreach (f ${arg_INPUT_FILES})
72         if (NOT IS_ABSOLUTE ${f})
73             set(f ${CMAKE_CURRENT_SOURCE_DIR}/${f})
74         endif ()
75         set(content "${content}${f}\n")
76     endforeach ()
77     file(WRITE ${idl_files_list} ${content})
78
79     set(args
80         --defines ${arg_FEATURES}
81         --generator ${arg_GENERATOR}
82         --outputDir ${arg_DESTINATION}
83         --idlFilesList ${idl_files_list}
84         --preprocessor "${CODE_GENERATOR_PREPROCESSOR}"
85         --idlAttributesFile ${idl_attributes_file})
86     if (arg_SUPPLEMENTAL_DEPFILE)
87         list(APPEND args --supplementalDependencyFile ${arg_SUPPLEMENTAL_DEPFILE})
88     endif ()
89     if (PROCESSOR_COUNT)
90         list(APPEND args --numOfJobs ${PROCESSOR_COUNT})
91     endif ()
92     foreach (i IN LISTS arg_IDL_INCLUDES)
93         if (IS_ABSOLUTE ${i})
94             list(APPEND args --include ${i})
95         else ()
96             list(APPEND args --include ${CMAKE_CURRENT_SOURCE_DIR}/${i})
97         endif ()
98     endforeach ()
99     foreach (i IN LISTS arg_PP_EXTRA_OUTPUT)
100         list(APPEND args --ppExtraOutput ${i})
101     endforeach ()
102     foreach (i IN LISTS arg_PP_EXTRA_ARGS)
103         list(APPEND args --ppExtraArgs ${i})
104     endforeach ()
105
106     set(common_generator_dependencies
107         ${WEBCORE_DIR}/bindings/scripts/generate-bindings.pl
108         ${SCRIPTS_BINDINGS}
109     )
110     if (EXISTS ${WEBCORE_DIR}/bindings/scripts/CodeGenerator${arg_GENERATOR}.pm)
111         list(APPEND common_generator_dependencies ${WEBCORE_DIR}/bindings/scripts/CodeGenerator${arg_GENERATOR}.pm)
112     endif ()
113     if (EXISTS ${arg_BASE_DIR}/CodeGenerator${arg_GENERATOR}.pm)
114         list(APPEND common_generator_dependencies ${arg_BASE_DIR}/CodeGenerator${arg_GENERATOR}.pm)
115     endif ()
116     foreach (i IN LISTS common_generator_dependencies)
117         list(APPEND args --generatorDependency ${i})
118     endforeach ()
119
120     set(gen_sources)
121     set(gen_headers)
122     foreach (_file ${arg_INPUT_FILES})
123         get_filename_component(_name ${_file} NAME_WE)
124         list(APPEND gen_sources ${arg_DESTINATION}/JS${_name}.cpp)
125         list(APPEND gen_headers ${arg_DESTINATION}/JS${_name}.h)
126     endforeach ()
127     set(${arg_OUTPUT_SOURCE} ${${arg_OUTPUT_SOURCE}} ${gen_sources} PARENT_SCOPE)
128     set(act_args)
129     if (${CMAKE_VERSION} VERSION_LESS 3.2)
130         set_source_files_properties(${gen_sources} ${gen_headers} PROPERTIES GENERATED 1)
131     else ()
132         list(APPEND act_args
133             BYPRODUCTS ${gen_sources} ${gen_headers}
134             USES_TERMINAL
135         )
136     endif ()
137     add_custom_target(${target}
138         COMMAND ${PERL_EXECUTABLE} ${binding_generator} ${args}
139         WORKING_DIRECTORY ${arg_BASE_DIR}
140         COMMENT "Generate bindings (${target})"
141         VERBATIM ${act_args})
142 endfunction()
143
144 macro(GENERATE_FONT_NAMES _infile)
145     set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_names.pl)
146     set(_arguments  --fonts ${_infile})
147     set(_outputfiles ${DERIVED_SOURCES_WEBCORE_DIR}/WebKitFontFamilyNames.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/WebKitFontFamilyNames.h)
148
149     add_custom_command(
150         OUTPUT  ${_outputfiles}
151         MAIN_DEPENDENCY ${_infile}
152         DEPENDS ${MAKE_NAMES_DEPENDENCIES} ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
153         COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR} ${_arguments}
154         VERBATIM)
155 endmacro()
156
157
158 macro(GENERATE_EVENT_FACTORY _infile _outfile)
159     set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_event_factory.pl)
160
161     add_custom_command(
162         OUTPUT  ${DERIVED_SOURCES_WEBCORE_DIR}/${_outfile}
163         MAIN_DEPENDENCY ${_infile}
164         DEPENDS ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
165         COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --input ${_infile} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR}
166         VERBATIM)
167 endmacro()
168
169
170 macro(GENERATE_EXCEPTION_CODE_DESCRIPTION _infile _outfile)
171     set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_dom_exceptions.pl)
172
173     add_custom_command(
174         OUTPUT  ${DERIVED_SOURCES_WEBCORE_DIR}/${_outfile}
175         MAIN_DEPENDENCY ${_infile}
176         DEPENDS ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
177         COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --input ${_infile} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR}
178         VERBATIM)
179 endmacro()
180
181
182 macro(GENERATE_SETTINGS_MACROS _infile _outfile)
183     set(NAMES_GENERATOR ${WEBCORE_DIR}/page/make_settings.pl)
184
185     add_custom_command(
186         OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/${_outfile} ${DERIVED_SOURCES_WEBCORE_DIR}/InternalSettingsGenerated.h ${DERIVED_SOURCES_WEBCORE_DIR}/InternalSettingsGenerated.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/InternalSettingsGenerated.idl
187         MAIN_DEPENDENCY ${_infile}
188         DEPENDS ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS}
189         COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --input ${_infile} --outputDir ${DERIVED_SOURCES_WEBCORE_DIR}
190         VERBATIM)
191 endmacro()
192
193
194 macro(GENERATE_DOM_NAMES _namespace _attrs)
195     set(NAMES_GENERATOR ${WEBCORE_DIR}/dom/make_names.pl)
196     set(_arguments  --attrs ${_attrs})
197     set(_outputfiles ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}Names.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}Names.h)
198     set(_extradef)
199     set(_tags)
200
201     foreach (f ${ARGN})
202         if (_tags)
203             set(_extradef "${_extradef} ${f}")
204         else ()
205             set(_tags ${f})
206         endif ()
207     endforeach ()
208
209     if (_tags)
210         set(_arguments "${_arguments}" --tags ${_tags} --factory --wrapperFactory)
211         set(_outputfiles "${_outputfiles}" ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}ElementFactory.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/${_namespace}ElementFactory.h ${DERIVED_SOURCES_WEBCORE_DIR}/JS${_namespace}ElementWrapperFactory.cpp ${DERIVED_SOURCES_WEBCORE_DIR}/JS${_namespace}ElementWrapperFactory.h)
212     endif ()
213
214     if (_extradef)
215         set(_additionArguments "${_additionArguments}" --extraDefines=${_extradef})
216     endif ()
217
218     add_custom_command(
219         OUTPUT  ${_outputfiles}
220         DEPENDS ${MAKE_NAMES_DEPENDENCIES} ${NAMES_GENERATOR} ${SCRIPTS_BINDINGS} ${_attrs} ${_tags}
221         COMMAND ${PERL_EXECUTABLE} ${NAMES_GENERATOR} --preprocessor "${CODE_GENERATOR_PREPROCESSOR_WITH_LINEMARKERS}" --outputDir ${DERIVED_SOURCES_WEBCORE_DIR} ${_arguments} ${_additionArguments}
222         VERBATIM)
223 endmacro()
224
225
226 macro(GENERATE_GRAMMAR _prefix _input _output_header _output_source _features)
227     # This is a workaround for winflexbison, which does not work corretly when
228     # run in a different working directory than the installation directory.
229     get_filename_component(_working_directory ${BISON_EXECUTABLE} PATH)
230
231     add_custom_command(
232         OUTPUT ${_output_header} ${_output_source}
233         MAIN_DEPENDENCY ${_input}
234         DEPENDS ${_input}
235         COMMAND ${PERL_EXECUTABLE} ${WEBCORE_DIR}/css/makegrammar.pl --outputDir ${DERIVED_SOURCES_WEBCORE_DIR} --extraDefines "${_features}" --preprocessor "${CODE_GENERATOR_PREPROCESSOR}" --bison "${BISON_EXECUTABLE}" --symbolsPrefix ${_prefix} ${_input}
236         WORKING_DIRECTORY ${_working_directory}
237         VERBATIM)
238 endmacro()
239
240 macro(MAKE_HASH_TOOLS _source)
241     get_filename_component(_name ${_source} NAME_WE)
242
243     if (${_source} STREQUAL "DocTypeStrings")
244         set(_hash_tools_h "${DERIVED_SOURCES_WEBCORE_DIR}/HashTools.h")
245     else ()
246         set(_hash_tools_h "")
247     endif ()
248
249     add_custom_command(
250         OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/${_name}.cpp ${_hash_tools_h}
251         MAIN_DEPENDENCY ${_source}.gperf
252         COMMAND ${PERL_EXECUTABLE} ${WEBCORE_DIR}/make-hash-tools.pl ${DERIVED_SOURCES_WEBCORE_DIR} ${_source}.gperf ${GPERF_EXECUTABLE}
253         VERBATIM)
254
255     unset(_name)
256     unset(_hash_tools_h)
257 endmacro()
258
259 macro(WEBKIT_WRAP_SOURCELIST)
260     foreach (_file ${ARGN})
261         get_filename_component(_basename ${_file} NAME_WE)
262         get_filename_component(_path ${_file} PATH)
263
264         if (NOT _file MATCHES "${DERIVED_SOURCES_WEBCORE_DIR}")
265             string(REGEX REPLACE "/" "\\\\\\\\" _sourcegroup "${_path}")
266             source_group("${_sourcegroup}" FILES ${_file})
267         endif ()
268     endforeach ()
269
270     source_group("DerivedSources" REGULAR_EXPRESSION "${DERIVED_SOURCES_WEBCORE_DIR}")
271 endmacro()
272
273 macro(WEBKIT_FRAMEWORK _target)
274     include_directories(${${_target}_INCLUDE_DIRECTORIES})
275     include_directories(SYSTEM ${${_target}_SYSTEM_INCLUDE_DIRECTORIES})
276     add_library(${_target} ${${_target}_LIBRARY_TYPE}
277         ${${_target}_HEADERS}
278         ${${_target}_SOURCES}
279     )
280     target_link_libraries(${_target} ${${_target}_LIBRARIES})
281     set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS "BUILDING_${_target}")
282
283     if (${_target}_OUTPUT_NAME)
284         set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${${_target}_OUTPUT_NAME})
285     endif ()
286
287     if (${_target}_PRE_BUILD_COMMAND)
288         add_custom_target(_${_target}_PreBuild COMMAND ${${_target}_PRE_BUILD_COMMAND} VERBATIM)
289         add_dependencies(${_target} _${_target}_PreBuild)
290     endif ()
291
292     if (${_target}_POST_BUILD_COMMAND)
293         add_custom_command(TARGET ${_target} POST_BUILD COMMAND ${${_target}_POST_BUILD_COMMAND} VERBATIM)
294     endif ()
295
296     if (APPLE AND NOT PORT STREQUAL "GTK" AND NOT ${_target} STREQUAL "WTF")
297         set_target_properties(${_target} PROPERTIES FRAMEWORK TRUE)
298         install(TARGETS ${_target} FRAMEWORK DESTINATION ${LIB_INSTALL_DIR})
299     endif ()
300 endmacro()
301
302 macro(WEBKIT_CREATE_FORWARDING_HEADER _target_directory _file)
303     get_filename_component(_source_path "${CMAKE_SOURCE_DIR}/Source/" ABSOLUTE)
304     get_filename_component(_absolute "${_file}" ABSOLUTE)
305     get_filename_component(_name "${_file}" NAME)
306     set(_target_filename "${_target_directory}/${_name}")
307
308     # Try to make the path in the forwarding header relative to the Source directory
309     # so that these forwarding headers are compatible with the ones created by the
310     # WebKit2 generate-forwarding-headers script.
311     string(REGEX REPLACE "${_source_path}/" "" _relative ${_absolute})
312
313     set(_content "#include \"${_relative}\"\n")
314
315     if (EXISTS "${_target_filename}")
316         file(READ "${_target_filename}" _old_content)
317     endif ()
318
319     if (NOT _old_content STREQUAL _content)
320         file(WRITE "${_target_filename}" "${_content}")
321     endif ()
322 endmacro()
323
324 macro(WEBKIT_CREATE_FORWARDING_HEADERS _framework)
325     # On Windows, we copy the entire contents of forwarding headers.
326     if (NOT WIN32)
327         set(_processing_directories 0)
328         set(_processing_files 0)
329         set(_target_directory "${DERIVED_SOURCES_DIR}/ForwardingHeaders/${_framework}")
330
331         file(GLOB _files "${_target_directory}/*.h")
332         foreach (_file ${_files})
333             file(READ "${_file}" _content)
334             string(REGEX MATCH "^#include \"([^\"]*)\"" _matched ${_content})
335             if (_matched AND NOT EXISTS "${CMAKE_SOURCE_DIR}/Source/${CMAKE_MATCH_1}")
336                file(REMOVE "${_file}")
337             endif ()
338         endforeach ()
339
340         foreach (_currentArg ${ARGN})
341             if ("${_currentArg}" STREQUAL "DIRECTORIES")
342                 set(_processing_directories 1)
343                 set(_processing_files 0)
344             elseif ("${_currentArg}" STREQUAL "FILES")
345                 set(_processing_directories 0)
346                 set(_processing_files 1)
347             elseif (_processing_directories)
348                 file(GLOB _files "${_currentArg}/*.h")
349                 foreach (_file ${_files})
350                     WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_file})
351                 endforeach ()
352             elseif (_processing_files)
353                 WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_currentArg})
354             endif ()
355         endforeach ()
356     endif ()
357 endmacro()
358
359 # Helper macro which wraps generate-message-receiver.py and generate-message-header.py scripts
360 #   _output_source is a list name which will contain generated sources.(eg. WebKit2_SOURCES)
361 #   _input_files are messages.in files to generate.
362 macro(GENERATE_WEBKIT2_MESSAGE_SOURCES _output_source _input_files)
363     foreach (_file ${_input_files})
364         get_filename_component(_name ${_file} NAME_WE)
365         add_custom_command(
366             OUTPUT ${DERIVED_SOURCES_WEBKIT2_DIR}/${_name}MessageReceiver.cpp ${DERIVED_SOURCES_WEBKIT2_DIR}/${_name}Messages.h
367             MAIN_DEPENDENCY ${_file}
368             DEPENDS ${WEBKIT2_DIR}/Scripts/webkit/__init__.py
369                     ${WEBKIT2_DIR}/Scripts/webkit/messages.py
370                     ${WEBKIT2_DIR}/Scripts/webkit/model.py
371                     ${WEBKIT2_DIR}/Scripts/webkit/parser.py
372             COMMAND ${PYTHON_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-message-receiver.py ${_file} > ${DERIVED_SOURCES_WEBKIT2_DIR}/${_name}MessageReceiver.cpp
373             COMMAND ${PYTHON_EXECUTABLE} ${WEBKIT2_DIR}/Scripts/generate-messages-header.py ${_file} > ${DERIVED_SOURCES_WEBKIT2_DIR}/${_name}Messages.h
374             WORKING_DIRECTORY ${WEBKIT2_DIR}
375             VERBATIM)
376
377         list(APPEND ${_output_source} ${DERIVED_SOURCES_WEBKIT2_DIR}/${_name}MessageReceiver.cpp)
378     endforeach ()
379 endmacro()
380
381 macro(MAKE_JS_FILE_ARRAYS _output_cpp _output_h _scripts _scripts_dependencies)
382     if (WIN32)
383         set(_python_path set "PYTHONPATH=${JavaScriptCore_SCRIPTS_DIR}" COMMAND)
384     else ()
385         set(_python_path "PYTHONPATH=${JavaScriptCore_SCRIPTS_DIR}")
386     endif ()
387
388     add_custom_command(
389         OUTPUT ${_output_h} ${_output_cpp}
390         MAIN_DEPENDENCY ${WEBCORE_DIR}/Scripts/make-js-file-arrays.py
391         DEPENDS ${${_scripts}}
392         COMMAND ${_python_path} ${PYTHON_EXECUTABLE} ${WEBCORE_DIR}/Scripts/make-js-file-arrays.py ${_output_h} ${_output_cpp} ${${_scripts}}
393         VERBATIM)
394     list(APPEND WebCore_DERIVED_SOURCES ${_output_cpp})
395     ADD_SOURCE_DEPENDENCIES(${${_scripts_dependencies}} ${_output_h} ${_output_cpp})
396 endmacro()
397
398 # Helper macro for using all-in-one builds
399 # This macro removes the sources included in the _all_in_one_file from the input _file_list.
400 # _file_list is a list of source files
401 # _all_in_one_file is an all-in-one cpp file includes other cpp files
402 # _result_file_list is the output file list
403 macro(PROCESS_ALLINONE_FILE _file_list _all_in_one_file _result_file_list _no_compile)
404     file(STRINGS ${_all_in_one_file} _all_in_one_file_content)
405     set(${_result_file_list} ${_file_list})
406     set(_allins "")
407     foreach (_line ${_all_in_one_file_content})
408         string(REGEX MATCH "^#include [\"<](.*)[\">]" _found ${_line})
409         if (_found)
410             list(APPEND _allins ${CMAKE_MATCH_1})
411         endif ()
412     endforeach ()
413
414     foreach (_allin ${_allins})
415         if (${_no_compile})
416             # For DerivedSources.cpp, we still need the derived sources to be generated, but we do not want them to be compiled
417             # individually. We add the header to the result file list so that CMake knows to keep generating the files.
418             string(REGEX REPLACE "(.*)\\.cpp" "\\1" _allin_no_ext ${_allin})
419             string(REGEX REPLACE ";([^;]*/)${_allin_no_ext}\\.cpp;" ";\\1${_allin_no_ext}.h;" _new_result "${${_result_file_list}};")
420         else ()
421             string(REGEX REPLACE ";[^;]*/${_allin};" ";" _new_result "${${_result_file_list}};")
422         endif ()
423         set(${_result_file_list} ${_new_result})
424     endforeach ()
425
426 endmacro()