[CMake] Properly test if compiler supports compiler flags
[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_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(WEBKIT_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     unset(_tmp)
29 endmacro()
30
31 macro(WEBKIT_ADD_PRECOMPILED_HEADER _header _cpp _source)
32     if (MSVC)
33         get_filename_component(PrecompiledBasename ${_cpp} NAME_WE)
34         file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_source}")
35         set(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${_source}/${PrecompiledBasename}.pch")
36         set(_sources ${${_source}})
37
38         # clang-cl requires /FI with /Yc
39         if (COMPILER_IS_CLANG_CL)
40             set_source_files_properties(${_cpp}
41                 PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\" /FI\"${_header}\""
42                 OBJECT_OUTPUTS "${PrecompiledBinary}")
43         else ()
44             set_source_files_properties(${_cpp}
45                 PROPERTIES COMPILE_FLAGS "/Yc\"${_header}\" /Fp\"${PrecompiledBinary}\""
46                 OBJECT_OUTPUTS "${PrecompiledBinary}")
47         endif ()
48         set_source_files_properties(${_sources}
49             PROPERTIES COMPILE_FLAGS "/Yu\"${_header}\" /FI\"${_header}\" /Fp\"${PrecompiledBinary}\"")
50
51         foreach (_src ${_sources})
52             WEBKIT_ADD_SOURCE_DEPENDENCIES(${_src} ${PrecompiledBinary})
53         endforeach ()
54
55         list(APPEND ${_source} ${_cpp})
56     endif ()
57     #FIXME: Add support for Xcode.
58 endmacro()
59
60 macro(WEBKIT_WRAP_SOURCELIST)
61     foreach (_file ${ARGN})
62         get_filename_component(_basename ${_file} NAME_WE)
63         get_filename_component(_path ${_file} PATH)
64
65         if (NOT _file MATCHES "${DERIVED_SOURCES_WEBCORE_DIR}")
66             string(REGEX REPLACE "/" "\\\\\\\\" _sourcegroup "${_path}")
67             source_group("${_sourcegroup}" FILES ${_file})
68         endif ()
69     endforeach ()
70
71     source_group("DerivedSources" REGULAR_EXPRESSION "${DERIVED_SOURCES_WEBCORE_DIR}")
72 endmacro()
73
74 macro(WEBKIT_FRAMEWORK_DECLARE _target)
75     # add_library() without any source files triggers CMake warning
76     # Addition of dummy "source" file does not result in any changes in generated build.ninja file
77     add_library(${_target} ${${_target}_LIBRARY_TYPE} "${CMAKE_BINARY_DIR}/cmakeconfig.h")
78 endmacro()
79
80 macro(WEBKIT_FRAMEWORK _target)
81     include_directories(SYSTEM ${${_target}_SYSTEM_INCLUDE_DIRECTORIES})
82     target_sources(${_target} PRIVATE
83         ${${_target}_HEADERS}
84         ${${_target}_SOURCES}
85     )
86     target_include_directories(${_target} PUBLIC "$<BUILD_INTERFACE:${${_target}_INCLUDE_DIRECTORIES}>")
87     target_include_directories(${_target} PRIVATE "$<BUILD_INTERFACE:${${_target}_PRIVATE_INCLUDE_DIRECTORIES}>")
88     target_link_libraries(${_target} ${${_target}_LIBRARIES})
89     set_target_properties(${_target} PROPERTIES COMPILE_DEFINITIONS "BUILDING_${_target}")
90
91     if (${_target}_OUTPUT_NAME)
92         set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${${_target}_OUTPUT_NAME})
93     endif ()
94
95     if (${_target}_PRE_BUILD_COMMAND)
96         add_custom_target(_${_target}_PreBuild COMMAND ${${_target}_PRE_BUILD_COMMAND} VERBATIM)
97         add_dependencies(${_target} _${_target}_PreBuild)
98     endif ()
99
100     if (${_target}_POST_BUILD_COMMAND)
101         add_custom_command(TARGET ${_target} POST_BUILD COMMAND ${${_target}_POST_BUILD_COMMAND} VERBATIM)
102     endif ()
103
104     if (APPLE AND NOT PORT STREQUAL "GTK" AND NOT ${${_target}_LIBRARY_TYPE} MATCHES STATIC)
105         set_target_properties(${_target} PROPERTIES FRAMEWORK TRUE)
106         install(TARGETS ${_target} FRAMEWORK DESTINATION ${LIB_INSTALL_DIR})
107     endif ()
108 endmacro()
109
110 macro(WEBKIT_CREATE_FORWARDING_HEADER _target_directory _file)
111     get_filename_component(_source_path "${CMAKE_SOURCE_DIR}/Source/" ABSOLUTE)
112     get_filename_component(_absolute "${_file}" ABSOLUTE)
113     get_filename_component(_name "${_file}" NAME)
114     set(_target_filename "${_target_directory}/${_name}")
115
116     # Try to make the path in the forwarding header relative to the Source directory
117     # so that these forwarding headers are compatible with the ones created by the
118     # WebKit2 generate-forwarding-headers script.
119     string(REGEX REPLACE "${_source_path}/" "" _relative ${_absolute})
120
121     set(_content "#include \"${_relative}\"\n")
122
123     if (EXISTS "${_target_filename}")
124         file(READ "${_target_filename}" _old_content)
125     endif ()
126
127     if (NOT _old_content STREQUAL _content)
128         file(WRITE "${_target_filename}" "${_content}")
129     endif ()
130 endmacro()
131
132 macro(WEBKIT_CREATE_FORWARDING_HEADERS _framework)
133     # On Windows, we copy the entire contents of forwarding headers.
134     if (NOT WIN32)
135         set(_processing_directories 0)
136         set(_processing_files 0)
137         set(_target_directory "${FORWARDING_HEADERS_DIR}/${_framework}")
138
139         file(GLOB _files "${_target_directory}/*.h")
140         foreach (_file ${_files})
141             file(READ "${_file}" _content)
142             string(REGEX MATCH "^#include \"([^\"]*)\"" _matched ${_content})
143             if (_matched AND NOT EXISTS "${CMAKE_SOURCE_DIR}/Source/${CMAKE_MATCH_1}")
144                file(REMOVE "${_file}")
145             endif ()
146         endforeach ()
147
148         foreach (_currentArg ${ARGN})
149             if ("${_currentArg}" STREQUAL "DIRECTORIES")
150                 set(_processing_directories 1)
151                 set(_processing_files 0)
152             elseif ("${_currentArg}" STREQUAL "FILES")
153                 set(_processing_directories 0)
154                 set(_processing_files 1)
155             elseif (_processing_directories)
156                 file(GLOB _files "${_currentArg}/*.h")
157                 foreach (_file ${_files})
158                     WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_file})
159                 endforeach ()
160             elseif (_processing_files)
161                 WEBKIT_CREATE_FORWARDING_HEADER(${_target_directory} ${_currentArg})
162             endif ()
163         endforeach ()
164     endif ()
165 endmacro()
166
167 # Helper macros for debugging CMake problems.
168 macro(WEBKIT_DEBUG_DUMP_COMMANDS)
169     set(CMAKE_VERBOSE_MAKEFILE ON)
170 endmacro()
171
172 macro(WEBKIT_DEBUG_DUMP_VARIABLES)
173     set_cmake_property(_variableNames VARIABLES)
174     foreach (_variableName ${_variableNames})
175        message(STATUS "${_variableName}=${${_variableName}}")
176     endforeach ()
177 endmacro()
178
179 # Append the given flag to the target property.
180 # Builds on top of get_target_property() and set_target_properties()
181 macro(WEBKIT_ADD_TARGET_PROPERTIES _target _property _flags)
182     get_target_property(_tmp ${_target} ${_property})
183     if (NOT _tmp)
184         set(_tmp "")
185     endif (NOT _tmp)
186
187     foreach (f ${_flags})
188         set(_tmp "${_tmp} ${f}")
189     endforeach (f ${_flags})
190
191     set_target_properties(${_target} PROPERTIES ${_property} ${_tmp})
192     unset(_tmp)
193 endmacro()
194
195 macro(WEBKIT_POPULATE_LIBRARY_VERSION library_name)
196     if (NOT DEFINED ${library_name}_VERSION_MAJOR)
197         set(${library_name}_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
198     endif ()
199     if (NOT DEFINED ${library_name}_VERSION_MINOR)
200         set(${library_name}_VERSION_MINOR ${PROJECT_VERSION_MINOR})
201     endif ()
202     if (NOT DEFINED ${library_name}_VERSION_MICRO)
203         set(${library_name}_VERSION_MICRO ${PROJECT_VERSION_MICRO})
204     endif ()
205     if (NOT DEFINED ${library_name}_VERSION)
206         set(${library_name}_VERSION ${PROJECT_VERSION})
207     endif ()
208 endmacro()