[CMake] Create targets before WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS is called
[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 include(CMakeParseArguments)
6 include(ProcessorCount)
7 ProcessorCount(PROCESSOR_COUNT)
8
9 macro(WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS)
10     set(_file ${CMAKE_CURRENT_SOURCE_DIR}/Platform${PORT}.cmake)
11     if (EXISTS ${_file})
12         message(STATUS "Using platform-specific CMakeLists: ${_file}")
13         include(${_file})
14     else ()
15         message(STATUS "Platform-specific CMakeLists not found: ${_file}")
16     endif ()
17 endmacro()
18
19 # Append the given dependencies to the source file
20 macro(ADD_SOURCE_DEPENDENCIES _source _deps)
21     set(_tmp)
22     get_source_file_property(_tmp ${_source} OBJECT_DEPENDS)
23     if (NOT _tmp)
24         set(_tmp "")
25     endif ()
26
27     foreach (f ${_deps})
28         list(APPEND _tmp "${f}")
29     endforeach ()
30
31     set_source_files_properties(${_source} PROPERTIES OBJECT_DEPENDS "${_tmp}")
32     unset(_tmp)
33 endmacro()
34
35 macro(ADD_PRECOMPILED_HEADER _header _cpp _source)
36     if (MSVC)
37         get_filename_component(PrecompiledBasename ${_cpp} NAME_WE)
38         file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_source}")
39         set(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${_source}/${PrecompiledBasename}.pch")
40         set(_sources ${${_source}})
41
42         # clang-cl requires /FI with /Yc
43         if (COMPILER_IS_CLANG_CL)
44             set_source_files_properties(${_cpp}
45                 PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\" /FI\"${_header}\""
46                 OBJECT_OUTPUTS "${PrecompiledBinary}")
47         else ()
48             set_source_files_properties(${_cpp}
49                 PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\""
50                 OBJECT_OUTPUTS "${PrecompiledBinary}")
51         endif ()
52         set_source_files_properties(${_sources}
53             PROPERTIES COMPILE_FLAGS "/Yu\"${_header}\" /FI\"${_header}\" /Fp\"${PrecompiledBinary}\"")
54
55         foreach (_src ${_sources})
56             ADD_SOURCE_DEPENDENCIES(${_src} ${PrecompiledBinary})
57         endforeach ()
58
59         list(APPEND ${_source} ${_cpp})
60     endif ()
61     #FIXME: Add support for Xcode.
62 endmacro()
63
64 macro(WEBKIT_WRAP_SOURCELIST)
65     foreach (_file ${ARGN})
66         get_filename_component(_basename ${_file} NAME_WE)
67         get_filename_component(_path ${_file} PATH)
68
69         if (NOT _file MATCHES "${DERIVED_SOURCES_WEBCORE_DIR}")
70             string(REGEX REPLACE "/" "\\\\\\\\" _sourcegroup "${_path}")
71             source_group("${_sourcegroup}" FILES ${_file})
72         endif ()
73     endforeach ()
74
75     source_group("DerivedSources" REGULAR_EXPRESSION "${DERIVED_SOURCES_WEBCORE_DIR}")
76 endmacro()
77
78 macro(WEBKIT_FRAMEWORK_DECLARE _target)
79     # add_library() without any source files triggers CMake warning
80     # Addition of dummy "source" file does not result in any changes in generated build.ninja file
81     add_library(${_target} ${${_target}_LIBRARY_TYPE} "${CMAKE_BINARY_DIR}/cmakeconfig.h")
82 endmacro()
83
84 macro(WEBKIT_FRAMEWORK _target)
85     include_directories(SYSTEM ${${_target}_SYSTEM_INCLUDE_DIRECTORIES})
86     target_sources(${_target} PRIVATE
87         ${${_target}_HEADERS}
88         ${${_target}_SOURCES}
89     )
90     target_include_directories(${_target} PUBLIC "$<BUILD_INTERFACE:${${_target}_INCLUDE_DIRECTORIES}>")
91     target_include_directories(${_target} PRIVATE "$<BUILD_INTERFACE:${${_target}_PRIVATE_INCLUDE_DIRECTORIES}>")
92     target_link_libraries(${_target} ${${_target}_LIBRARIES})
93     set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS "BUILDING_${_target}")
94
95     if (${_target}_OUTPUT_NAME)
96         set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${${_target}_OUTPUT_NAME})
97     endif ()
98
99     if (${_target}_PRE_BUILD_COMMAND)
100         add_custom_target(_${_target}_PreBuild COMMAND ${${_target}_PRE_BUILD_COMMAND} VERBATIM)
101         add_dependencies(${_target} _${_target}_PreBuild)
102     endif ()
103
104     if (${_target}_POST_BUILD_COMMAND)
105         add_custom_command(TARGET ${_target} POST_BUILD COMMAND ${${_target}_POST_BUILD_COMMAND} VERBATIM)
106     endif ()
107
108     if (APPLE AND NOT PORT STREQUAL "GTK" AND NOT ${${_target}_LIBRARY_TYPE} MATCHES STATIC)
109         set_target_properties(${_target} PROPERTIES FRAMEWORK TRUE)
110         install(TARGETS ${_target} FRAMEWORK DESTINATION ${LIB_INSTALL_DIR})
111     endif ()
112 endmacro()
113
114 macro(WEBKIT_CREATE_FORWARDING_HEADER _target_directory _file)
115     get_filename_component(_source_path "${CMAKE_SOURCE_DIR}/Source/" ABSOLUTE)
116     get_filename_component(_absolute "${_file}" ABSOLUTE)
117     get_filename_component(_name "${_file}" NAME)
118     set(_target_filename "${_target_directory}/${_name}")
119
120     # Try to make the path in the forwarding header relative to the Source directory
121     # so that these forwarding headers are compatible with the ones created by the
122     # WebKit2 generate-forwarding-headers script.
123     string(REGEX REPLACE "${_source_path}/" "" _relative ${_absolute})
124
125     set(_content "#include \"${_relative}\"\n")
126
127     if (EXISTS "${_target_filename}")
128         file(READ "${_target_filename}" _old_content)
129     endif ()
130
131     if (NOT _old_content STREQUAL _content)
132         file(WRITE "${_target_filename}" "${_content}")
133     endif ()
134 endmacro()
135
136 macro(WEBKIT_CREATE_FORWARDING_HEADERS _framework)
137     # On Windows, we copy the entire contents of forwarding headers.
138     if (NOT WIN32)
139         set(_processing_directories 0)
140         set(_processing_files 0)
141         set(_target_directory "${FORWARDING_HEADERS_DIR}/${_framework}")
142
143         file(GLOB _files "${_target_directory}/*.h")
144         foreach (_file ${_files})
145             file(READ "${_file}" _content)
146             string(REGEX MATCH "^#include \"([^\"]*)\"" _matched ${_content})
147             if (_matched AND NOT EXISTS "${CMAKE_SOURCE_DIR}/Source/${CMAKE_MATCH_1}")
148                file(REMOVE "${_file}")
149             endif ()
150         endforeach ()
151
152         foreach (_currentArg ${ARGN})
153             if ("${_currentArg}" STREQUAL "DIRECTORIES")
154                 set(_processing_directories 1)
155                 set(_processing_files 0)
156             elseif ("${_currentArg}" STREQUAL "FILES")
157                 set(_processing_directories 0)
158                 set(_processing_files 1)
159             elseif (_processing_directories)
160                 file(GLOB _files "${_currentArg}/*.h")
161                 foreach (_file ${_files})
162                     WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_file})
163                 endforeach ()
164             elseif (_processing_files)
165                 WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_currentArg})
166             endif ()
167         endforeach ()
168     endif ()
169 endmacro()
170
171 # Helper macros for debugging CMake problems.
172 macro(WEBKIT_DEBUG_DUMP_COMMANDS)
173     set(CMAKE_VERBOSE_MAKEFILE ON)
174 endmacro()
175
176 macro(WEBKIT_DEBUG_DUMP_VARIABLES)
177     set_cmake_property(_variableNames VARIABLES)
178     foreach (_variableName ${_variableNames})
179        message(STATUS "${_variableName}=${${_variableName}}")
180     endforeach ()
181 endmacro()
182
183 # Sets extra compile flags for a target, depending on the compiler being used.
184 # Currently, only GCC is supported.
185 macro(WEBKIT_SET_EXTRA_COMPILER_FLAGS _target)
186     set(options ENABLE_WERROR IGNORECXX_WARNINGS)
187     CMAKE_PARSE_ARGUMENTS("OPTION" "${options}" "" "" ${ARGN})
188     if (COMPILER_IS_GCC_OR_CLANG)
189         get_target_property(OLD_COMPILE_FLAGS ${_target} COMPILE_FLAGS)
190         if (${OLD_COMPILE_FLAGS} STREQUAL "OLD_COMPILE_FLAGS-NOTFOUND")
191             set(OLD_COMPILE_FLAGS "")
192         endif ()
193
194         if (NOT WIN32)
195             get_target_property(TARGET_TYPE ${_target} TYPE)
196             if (${TARGET_TYPE} STREQUAL "STATIC_LIBRARY") # -fPIC is automatically added to shared libraries
197                 set(OLD_COMPILE_FLAGS "-fPIC ${OLD_COMPILE_FLAGS}")
198             endif ()
199         endif ()
200
201         # Suppress -Wparentheses-equality warning of Clang
202         if (COMPILER_IS_CLANG)
203             set(OLD_COMPILE_FLAGS "-Wno-parentheses-equality ${OLD_COMPILE_FLAGS}")
204         endif ()
205
206         # Enable warnings by default
207         if (NOT ${OPTION_IGNORECXX_WARNINGS})
208             set(OLD_COMPILE_FLAGS "-Wall -Wextra -Wcast-align -Wformat-security -Wmissing-format-attribute -Wpointer-arith -Wundef -Wwrite-strings ${OLD_COMPILE_FLAGS}")
209         endif ()
210
211         # Enable errors on warning
212         if (OPTION_ENABLE_WERROR)
213             set(OLD_COMPILE_FLAGS "-Werror ${OLD_COMPILE_FLAGS}")
214         endif ()
215
216         set_target_properties(${_target} PROPERTIES
217             COMPILE_FLAGS "${OLD_COMPILE_FLAGS}")
218
219         unset(OLD_COMPILE_FLAGS)
220     endif ()
221 endmacro()
222
223 # Append the given flag to the target property.
224 # Builds on top of get_target_property() and set_target_properties()
225 macro(ADD_TARGET_PROPERTIES _target _property _flags)
226     get_target_property(_tmp ${_target} ${_property})
227     if (NOT _tmp)
228         set(_tmp "")
229     endif (NOT _tmp)
230
231     foreach (f ${_flags})
232         set(_tmp "${_tmp} ${f}")
233     endforeach (f ${_flags})
234
235     set_target_properties(${_target} PROPERTIES ${_property} ${_tmp})
236     unset(_tmp)
237 endmacro(ADD_TARGET_PROPERTIES _target _property _flags)
238
239 macro(POPULATE_LIBRARY_VERSION library_name)
240     if (NOT DEFINED ${library_name}_VERSION_MAJOR)
241         set(${library_name}_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
242     endif ()
243     if (NOT DEFINED ${library_name}_VERSION_MINOR)
244         set(${library_name}_VERSION_MINOR ${PROJECT_VERSION_MINOR})
245     endif ()
246     if (NOT DEFINED ${library_name}_VERSION_MICRO)
247         set(${library_name}_VERSION_MICRO ${PROJECT_VERSION_MICRO})
248     endif ()
249     if (NOT DEFINED ${library_name}_VERSION)
250         set(${library_name}_VERSION ${PROJECT_VERSION})
251     endif ()
252 endmacro()