6d58d57e63737e4cc05bcd408a1125be4ced3cca
[WebKit-https.git] / Source / cmake / WebKitMacros.cmake
1 # This file is for macros that are used by multiple projects. If your macro is
2 # exclusively needed in only one subdirectory of Source (e.g. only needed by
3 # WebCore), then put it there instead.
4
5 macro(WEBKIT_COMPUTE_SOURCES _framework)
6     foreach (_sourcesListFile IN LISTS ${_framework}_UNIFIED_SOURCE_LIST_FILES)
7       configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${_sourcesListFile}" "${DERIVED_SOURCES_DIR}/${_framework}/${_sourcesListFile}" COPYONLY)
8       message(STATUS "Using source list file: ${_sourcesListFile}")
9
10       list(APPEND _sourceListFileTruePaths "${CMAKE_CURRENT_SOURCE_DIR}/${_sourcesListFile}")
11     endforeach ()
12
13     if (WIN32 AND INTERNAL_BUILD)
14         set(WTF_SCRIPTS_DIR "${CMAKE_BINARY_DIR}/../include/private/WTF/Scripts")
15     else ()
16         set(WTF_SCRIPTS_DIR "${FORWARDING_HEADERS_DIR}/wtf/Scripts")
17     endif ()
18
19     if (ENABLE_UNIFIED_BUILDS)
20         execute_process(COMMAND ${RUBY_EXECUTABLE} ${WTF_SCRIPTS_DIR}/generate-unified-source-bundles.rb
21             "--derived-sources-path" "${DERIVED_SOURCES_DIR}/${_framework}"
22             "--source-tree-path" ${CMAKE_CURRENT_SOURCE_DIR}
23             "--print-bundled-sources"
24             "--feature-flags" "${UNIFIED_SOURCE_LIST_ENABLED_FEATURES}"
25             ${_sourceListFileTruePaths}
26             RESULT_VARIABLE _resultTmp
27             OUTPUT_VARIABLE _outputTmp)
28
29         if (${_resultTmp})
30              message(FATAL_ERROR "generate-unified-source-bundles.rb exited with non-zero status, exiting")
31         endif ()
32
33         foreach (_sourceFileTmp IN LISTS _outputTmp)
34             set_source_files_properties(${_sourceFileTmp} PROPERTIES HEADER_FILE_ONLY ON)
35             list(APPEND ${_framework}_HEADERS ${_sourceFileTmp})
36         endforeach ()
37         unset(_sourceFileTmp)
38
39         execute_process(COMMAND ${RUBY_EXECUTABLE} ${WTF_SCRIPTS_DIR}/generate-unified-source-bundles.rb
40             "--derived-sources-path" "${DERIVED_SOURCES_DIR}/${_framework}"
41             "--source-tree-path" ${CMAKE_CURRENT_SOURCE_DIR}
42             "--feature-flags" "${UNIFIED_SOURCE_LIST_ENABLED_FEATURES}"
43             ${_sourceListFileTruePaths}
44             RESULT_VARIABLE  _resultTmp
45             OUTPUT_VARIABLE _outputTmp)
46
47         if (${_resultTmp})
48             message(FATAL_ERROR "generate-unified-source-bundles.rb exited with non-zero status, exiting")
49         endif ()
50
51         list(APPEND ${_framework}_SOURCES ${_outputTmp})
52         unset(_resultTmp)
53         unset(_outputTmp)
54     else ()
55         execute_process(COMMAND ${RUBY_EXECUTABLE} ${WTF_SCRIPTS_DIR}/generate-unified-source-bundles.rb
56             "--derived-sources-path" "${DERIVED_SOURCES_DIR}/${_framework}"
57             "--source-tree-path" ${CMAKE_CURRENT_SOURCE_DIR}
58             "--print-all-sources"
59             "--feature-flags" "${UNIFIED_SOURCE_LIST_ENABLED_FEATURES}"
60             ${_sourceListFileTruePaths}
61             RESULT_VARIABLE _resultTmp
62             OUTPUT_VARIABLE _outputTmp)
63
64         if (${_resultTmp})
65              message(FATAL_ERROR "generate-unified-source-bundles.rb exited with non-zero status, exiting")
66         endif ()
67
68         list(APPEND ${_framework}_SOURCES ${_outputTmp})
69         unset(_resultTmp)
70         unset(_outputTmp)
71     endif ()
72 endmacro()
73
74 macro(WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS)
75     set(_file ${CMAKE_CURRENT_SOURCE_DIR}/Platform${PORT}.cmake)
76     if (EXISTS ${_file})
77         message(STATUS "Using platform-specific CMakeLists: ${_file}")
78         include(${_file})
79     else ()
80         message(STATUS "Platform-specific CMakeLists not found: ${_file}")
81     endif ()
82 endmacro()
83
84 # Append the given dependencies to the source file
85 macro(WEBKIT_ADD_SOURCE_DEPENDENCIES _source _deps)
86     set(_tmp)
87     get_source_file_property(_tmp ${_source} OBJECT_DEPENDS)
88     if (NOT _tmp)
89         set(_tmp "")
90     endif ()
91
92     foreach (f ${_deps})
93         list(APPEND _tmp "${f}")
94     endforeach ()
95
96     set_source_files_properties(${_source} PROPERTIES OBJECT_DEPENDS "${_tmp}")
97     unset(_tmp)
98 endmacro()
99
100 macro(WEBKIT_ADD_PRECOMPILED_HEADER _header _cpp _source)
101     if (MSVC)
102         get_filename_component(PrecompiledBasename ${_cpp} NAME_WE)
103         file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_source}")
104         set(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${_source}/${PrecompiledBasename}.pch")
105         set(_sources ${${_source}})
106
107         # clang-cl requires /FI with /Yc
108         if (COMPILER_IS_CLANG_CL)
109             set_source_files_properties(${_cpp}
110                 PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\" /FI\"${_header}\""
111                 OBJECT_OUTPUTS "${PrecompiledBinary}")
112         else ()
113             set_source_files_properties(${_cpp}
114                 PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\""
115                 OBJECT_OUTPUTS "${PrecompiledBinary}")
116         endif ()
117         set_source_files_properties(${_sources}
118             PROPERTIES COMPILE_FLAGS "/Yu\"${_header}\" /FI\"${_header}\" /Fp\"${PrecompiledBinary}\"")
119
120         foreach (_src ${_sources})
121             WEBKIT_ADD_SOURCE_DEPENDENCIES(${_src} ${PrecompiledBinary})
122         endforeach ()
123
124         list(APPEND ${_source} ${_cpp})
125     endif ()
126     #FIXME: Add support for Xcode.
127 endmacro()
128
129 macro(WEBKIT_WRAP_SOURCELIST)
130     foreach (_file ${ARGN})
131         get_filename_component(_basename ${_file} NAME_WE)
132         get_filename_component(_path ${_file} PATH)
133
134         if (NOT _file MATCHES "${DERIVED_SOURCES_WEBCORE_DIR}")
135             string(REGEX REPLACE "/" "\\\\\\\\" _sourcegroup "${_path}")
136             source_group("${_sourcegroup}" FILES ${_file})
137         endif ()
138     endforeach ()
139
140     source_group("DerivedSources" REGULAR_EXPRESSION "${DERIVED_SOURCES_WEBCORE_DIR}")
141 endmacro()
142
143 macro(WEBKIT_FRAMEWORK_DECLARE _target)
144     # add_library() without any source files triggers CMake warning
145     # Addition of dummy "source" file does not result in any changes in generated build.ninja file
146     add_library(${_target} ${${_target}_LIBRARY_TYPE} "${CMAKE_BINARY_DIR}/cmakeconfig.h")
147 endmacro()
148
149 macro(WEBKIT_FRAMEWORK _target)
150     target_sources(${_target} PRIVATE
151         ${${_target}_HEADERS}
152         ${${_target}_SOURCES}
153     )
154     target_include_directories(${_target} PUBLIC "$<BUILD_INTERFACE:${${_target}_INCLUDE_DIRECTORIES}>")
155     target_include_directories(${_target} SYSTEM PRIVATE "$<BUILD_INTERFACE:${${_target}_SYSTEM_INCLUDE_DIRECTORIES}>")
156     target_include_directories(${_target} PRIVATE "$<BUILD_INTERFACE:${${_target}_PRIVATE_INCLUDE_DIRECTORIES}>")
157     target_link_libraries(${_target} ${${_target}_LIBRARIES})
158     set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS "BUILDING_${_target}")
159
160     if (${_target}_OUTPUT_NAME)
161         set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${${_target}_OUTPUT_NAME})
162     endif ()
163
164     if (${_target}_PRE_BUILD_COMMAND)
165         add_custom_target(_${_target}_PreBuild COMMAND ${${_target}_PRE_BUILD_COMMAND} VERBATIM)
166         add_dependencies(${_target} _${_target}_PreBuild)
167     endif ()
168
169     if (${_target}_POST_BUILD_COMMAND)
170         add_custom_command(TARGET ${_target} POST_BUILD COMMAND ${${_target}_POST_BUILD_COMMAND} VERBATIM)
171     endif ()
172
173     if (APPLE AND NOT PORT STREQUAL "GTK" AND NOT ${${_target}_LIBRARY_TYPE} MATCHES STATIC)
174         set_target_properties(${_target} PROPERTIES FRAMEWORK TRUE)
175         install(TARGETS ${_target} FRAMEWORK DESTINATION ${LIB_INSTALL_DIR})
176     endif ()
177 endmacro()
178
179 macro(WEBKIT_CREATE_FORWARDING_HEADER _target_directory _file)
180     get_filename_component(_source_path "${CMAKE_SOURCE_DIR}/Source/" ABSOLUTE)
181     get_filename_component(_absolute "${_file}" ABSOLUTE)
182     get_filename_component(_name "${_file}" NAME)
183     set(_target_filename "${_target_directory}/${_name}")
184
185     # Try to make the path in the forwarding header relative to the Source directory
186     # so that these forwarding headers are compatible with the ones created by the
187     # WebKit2 generate-forwarding-headers script.
188     string(REGEX REPLACE "${_source_path}/" "" _relative ${_absolute})
189
190     set(_content "#include \"${_relative}\"\n")
191
192     if (EXISTS "${_target_filename}")
193         file(READ "${_target_filename}" _old_content)
194     endif ()
195
196     if (NOT _old_content STREQUAL _content)
197         file(WRITE "${_target_filename}" "${_content}")
198     endif ()
199 endmacro()
200
201 macro(WEBKIT_CREATE_FORWARDING_HEADERS _framework)
202     # On Windows, we copy the entire contents of forwarding headers.
203     if (NOT WIN32)
204         set(_processing_directories 0)
205         set(_processing_files 0)
206         set(_target_directory "${FORWARDING_HEADERS_DIR}/${_framework}")
207
208         file(GLOB _files "${_target_directory}/*.h")
209         foreach (_file ${_files})
210             file(READ "${_file}" _content)
211             string(REGEX MATCH "^#include \"([^\"]*)\"" _matched ${_content})
212             if (_matched AND NOT EXISTS "${CMAKE_SOURCE_DIR}/Source/${CMAKE_MATCH_1}")
213                file(REMOVE "${_file}")
214             endif ()
215         endforeach ()
216
217         foreach (_currentArg ${ARGN})
218             if ("${_currentArg}" STREQUAL "DIRECTORIES")
219                 set(_processing_directories 1)
220                 set(_processing_files 0)
221             elseif ("${_currentArg}" STREQUAL "FILES")
222                 set(_processing_directories 0)
223                 set(_processing_files 1)
224             elseif (_processing_directories)
225                 file(GLOB _files "${_currentArg}/*.h")
226                 foreach (_file ${_files})
227                     WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_file})
228                 endforeach ()
229             elseif (_processing_files)
230                 WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_currentArg})
231             endif ()
232         endforeach ()
233     endif ()
234 endmacro()
235
236 function(WEBKIT_MAKE_FORWARDING_HEADERS framework)
237     set(options FLATTENED)
238     set(oneValueArgs DESTINATION TARGET_NAME)
239     set(multiValueArgs DIRECTORIES EXTRA_DIRECTORIES DERIVED_SOURCE_DIRECTORIES FILES)
240     cmake_parse_arguments(opt "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
241     set(headers ${opt_FILES})
242     if (opt_DESTINATION)
243         set(destination ${opt_DESTINATION})
244     else ()
245         set(destination ${FORWARDING_HEADERS_DIR}/${framework})
246     endif ()
247     file(MAKE_DIRECTORY ${destination})
248     foreach (dir IN LISTS opt_DIRECTORIES)
249         file(GLOB files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${dir}/*.h)
250         list(APPEND headers ${files})
251     endforeach ()
252     set(fwd_headers)
253     foreach (header IN LISTS headers)
254         if (opt_FLATTENED)
255             get_filename_component(header_filename ${header} NAME)
256             set(fwd_header ${destination}/${header_filename})
257         else ()
258             get_filename_component(header_dir ${header} DIRECTORY)
259             file(MAKE_DIRECTORY ${destination}/${header_dir})
260             set(fwd_header ${destination}/${header})
261         endif ()
262         add_custom_command(OUTPUT ${fwd_header}
263             COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${header} ${fwd_header}
264             MAIN_DEPENDENCY ${header}
265             VERBATIM
266         )
267         list(APPEND fwd_headers ${fwd_header})
268     endforeach ()
269     foreach (dir IN LISTS opt_EXTRA_DIRECTORIES)
270         set(dir ${CMAKE_CURRENT_SOURCE_DIR}/${dir})
271         file(GLOB_RECURSE files RELATIVE ${dir} ${dir}/*.h)
272         foreach (header IN LISTS files)
273             get_filename_component(header_dir ${header} DIRECTORY)
274             file(MAKE_DIRECTORY ${destination}/${header_dir})
275             set(fwd_header ${destination}/${header})
276             add_custom_command(OUTPUT ${fwd_header}
277                 COMMAND ${CMAKE_COMMAND} -E copy ${dir}/${header} ${fwd_header}
278                 MAIN_DEPENDENCY ${dir}/${header}
279                 VERBATIM
280             )
281             list(APPEND fwd_headers ${fwd_header})
282         endforeach ()
283     endforeach ()
284     if (opt_TARGET_NAME)
285         set(target_name ${opt_TARGET_NAME})
286     else ()
287         set(target_name ${framework}ForwardingHeaders)
288     endif ()
289     add_custom_target(${target_name} DEPENDS ${fwd_headers})
290     add_dependencies(${framework} ${target_name})
291     if (opt_DERIVED_SOURCE_DIRECTORIES)
292         set(script ${CMAKE_CURRENT_BINARY_DIR}/makeForwardingHeaders.cmake)
293         set(content "")
294         foreach (dir IN LISTS opt_DERIVED_SOURCE_DIRECTORIES)
295             string(CONCAT content ${content}
296                 "file(GLOB headers \"${dir}/*.h\")\n"
297                 "foreach (header IN LISTS headers)\n"
298                 "    get_filename_component(header_filename \${header} NAME)\n"
299                 "    execute_process(COMMAND \${CMAKE_COMMAND} -E copy_if_different \${header} ${destination}/\${header_filename} RESULT_VARIABLE result)\n"
300                 "    if (NOT \${result} EQUAL 0)\n"
301                 "        message(FATAL_ERROR \"Failed to copy \${header}: \${result}\")\n"
302                 "    endif ()\n"
303                 "endforeach ()\n"
304             )
305         endforeach ()
306         file(WRITE ${script} ${content})
307         add_custom_command(TARGET ${framework} POST_BUILD
308             COMMAND ${CMAKE_COMMAND} -P ${script}
309             VERBATIM
310         )
311     endif ()
312 endfunction()
313
314 # Helper macros for debugging CMake problems.
315 macro(WEBKIT_DEBUG_DUMP_COMMANDS)
316     set(CMAKE_VERBOSE_MAKEFILE ON)
317 endmacro()
318
319 macro(WEBKIT_DEBUG_DUMP_VARIABLES)
320     set_cmake_property(_variableNames VARIABLES)
321     foreach (_variableName ${_variableNames})
322        message(STATUS "${_variableName}=${${_variableName}}")
323     endforeach ()
324 endmacro()
325
326 # Append the given flag to the target property.
327 # Builds on top of get_target_property() and set_target_properties()
328 macro(WEBKIT_ADD_TARGET_PROPERTIES _target _property _flags)
329     get_target_property(_tmp ${_target} ${_property})
330     if (NOT _tmp)
331         set(_tmp "")
332     endif (NOT _tmp)
333
334     foreach (f ${_flags})
335         set(_tmp "${_tmp} ${f}")
336     endforeach (f ${_flags})
337
338     set_target_properties(${_target} PROPERTIES ${_property} ${_tmp})
339     unset(_tmp)
340 endmacro()
341
342 macro(WEBKIT_POPULATE_LIBRARY_VERSION library_name)
343     if (NOT DEFINED ${library_name}_VERSION_MAJOR)
344         set(${library_name}_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
345     endif ()
346     if (NOT DEFINED ${library_name}_VERSION_MINOR)
347         set(${library_name}_VERSION_MINOR ${PROJECT_VERSION_MINOR})
348     endif ()
349     if (NOT DEFINED ${library_name}_VERSION_MICRO)
350         set(${library_name}_VERSION_MICRO ${PROJECT_VERSION_MICRO})
351     endif ()
352     if (NOT DEFINED ${library_name}_VERSION)
353         set(${library_name}_VERSION ${PROJECT_VERSION})
354     endif ()
355 endmacro()
356
357 macro(WEBKIT_CREATE_SYMLINK target src dest)
358     add_custom_command(TARGET ${target} POST_BUILD
359         COMMAND ln -sf ${src} ${dest}
360         DEPENDS ${dest}
361         COMMENT "Create symlink from ${src} to ${dest}")
362 endmacro()