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