bump product version to 6.4.0.3
[LibreOffice.git] / compilerplugins / Makefile-clang.mk
blob0965c74636fc60a583c9bb4c5f0091e28d2f4e0b
2 # This file is part of the LibreOffice project.
4 # This Source Code Form is subject to the terms of the Mozilla Public
5 # License, v. 2.0. If a copy of the MPL was not distributed with this
6 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 # Make sure variables in this Makefile do not conflict with other variables (e.g. from gbuild).
11 # Set to 1 if you need to debug the plugin).
12 CLANGDEBUG=
14 # Compile flags, you may occasionally want to override these:
15 ifeq ($(OS),WNT)
16 # See LLVM's cmake/modules/AddLLVM.cmake and LLVM build's
17 # tools/llvm-config/BuildVariables.inc:
18 # * Ignore "warning C4141: 'inline': used more than once" as emitted upon
19 # "LLVM_ATTRIBUTE_ALWAYS_INLINE inline" in various LLVM include files.
20 # * Ignore "warning C4577: 'noexcept' used with no exception handling mode
21 # specified; termination on exception is not guaranteed. Specify /EHsc".
22 CLANGCXXFLAGS=/nologo /D_HAS_EXCEPTIONS=0 /wd4141 /wd4577 /EHs-c- /GR-
23 ifeq ($(CLANGDEBUG),)
24 CLANGCXXFLAGS+=/O2 /Oi
25 else
26 CLANGCXXFLAGS+=/DEBUG /Od
27 endif
28 else # WNT
29 CLANGCXXFLAGS=-Wall -Wextra -Wundef
30 ifeq ($(CLANGDEBUG),)
31 CLANGCXXFLAGS+=-O2
32 else
33 CLANGCXXFLAGS+=-g -O0 -UNDEBUG
34 endif
35 endif
37 # Whether to make plugins use one shared ASTRecursiveVisitor (plugins run faster).
38 # By default enabled, disable if you work on an affected plugin (re-generating takes time).
39 LO_CLANG_SHARED_PLUGINS=1
40 #TODO: Windows doesn't use LO_CLANG_SHARED_PLUGINS for now, see corresponding TODO comment in
41 # configure.ac:
42 ifeq ($(OS),WNT)
43 LO_CLANG_SHARED_PLUGINS=
44 endif
46 # Whether to use precompiled headers for the sources. This is actually controlled
47 # by gb_ENABLE_PCH like everywhere else, but unsetting this disables PCH.
48 LO_CLANG_USE_PCH=1
50 # Whether to use precompiled headers for the analyzer too. Does not apply to compiling sources.
51 LO_CLANG_USE_ANALYZER_PCH=1
53 # The uninteresting rest.
55 include $(SRCDIR)/solenv/gbuild/gbuild.mk
56 include $(SRCDIR)/solenv/gbuild/Output.mk
58 CLANG_COMMA :=,
60 ifeq ($(OS),WNT)
61 CLANG_DL_EXT = .dll
62 CLANG_EXE_EXT = .exe
63 else
64 CLANG_DL_EXT = .so
65 CLANG_EXE_EXT =
66 endif
68 # Clang headers require these.
69 CLANGDEFS:=$(COMPILER_PLUGINS_CXXFLAGS)
70 # All include locations needed (using -isystem silences various warnings when
71 # including those files):
72 ifneq ($(OS),WNT)
73 CLANGDEFS:=$(filter-out -isystem/usr/include,$(foreach opt,$(CLANGDEFS),$(patsubst -I%,-isystem%,$(opt))))
74 endif
76 # Clang/LLVM libraries are intentionally not linked in, they are usually built as static libraries, which means the resulting
77 # plugin would be big (even though the clang binary already includes it all) and it'd be necessary to explicitly specify
78 # also all the dependency libraries.
80 CLANGINDIR=$(SRCDIR)/compilerplugins/clang
81 # Cannot use $(WORKDIR), the plugin should survive even 'make clean', otherwise the rebuilt
82 # plugin will cause cache misses with ccache.
83 CLANGOUTDIR=$(BUILDDIR)/compilerplugins/clang
84 CLANGOBJDIR=$(CLANGOUTDIR)/obj
86 ifdef LO_CLANG_SHARED_PLUGINS
87 CLANGCXXFLAGS+=-DLO_CLANG_SHARED_PLUGINS
88 endif
90 ifneq ($(CLANGDEBUG),)
91 ifeq ($(HAVE_GCC_SPLIT_DWARF),TRUE)
92 CLANGCXXFLAGS+=-gsplit-dwarf
93 endif
94 endif
96 QUIET=$(if $(verbose),,@)
98 ifneq ($(ENABLE_WERROR),)
99 ifeq ($(OS),WNT)
100 CLANGWERROR :=
101 #TODO: /WX
102 else
103 CLANGWERROR := -Werror
104 endif
105 endif
107 ifneq ($(LO_CLANG_USE_PCH),)
108 # Reset and enable only if actually supported and enabled.
109 LO_CLANG_USE_PCH=
110 ifneq ($(gb_ENABLE_PCH),)
111 ifneq ($(OS),WNT)
112 # Currently only Clang PCH is supported (which should usually be the case, as Clang is usually self-built).
113 ifneq ($(findstring clang,$(COMPILER_PLUGINS_CXX)),)
114 LO_CLANG_USE_PCH=1
115 endif
116 endif
117 endif
118 endif
121 compilerplugins: compilerplugins-build
123 ifdef LO_CLANG_SHARED_PLUGINS
124 # The shared source, intentionally put first in the list because it takes the longest to build.
125 CLANGSRCOUTDIR=$(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx
126 CLANGSRC+=$(CLANGSRCOUTDIR)
127 endif
128 # The list of source files, generated automatically (all files in clang/, but not subdirs).
129 CLANGSRCINDIR=$(foreach src,$(wildcard $(CLANGINDIR)/*.cxx), $(notdir $(src)))
130 CLANGSRC+=$(CLANGSRCINDIR)
132 # Remember the sources and if they have changed, force plugin relinking.
133 CLANGSRCCHANGED= \
134 $(shell mkdir -p $(CLANGOUTDIR) ; \
135 echo $(CLANGSRC) | sort > $(CLANGOUTDIR)/sources-new.txt; \
136 if diff $(CLANGOUTDIR)/sources.txt $(CLANGOUTDIR)/sources-new.txt >/dev/null 2>/dev/null; then \
137 echo 0; \
138 else \
139 mv $(CLANGOUTDIR)/sources-new.txt $(CLANGOUTDIR)/sources.txt; \
140 echo 1; \
141 fi; \
143 ifeq ($(CLANGSRCCHANGED),1)
144 .PHONY: CLANGFORCE
145 CLANGFORCE:
146 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): CLANGFORCE
147 endif
148 # Make the .so also explicitly depend on the sources list, to force update in case CLANGSRCCHANGED was e.g. during 'make clean'.
149 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(CLANGOUTDIR)/sources.txt
150 $(CLANGOUTDIR)/sources.txt:
151 touch $@
153 compilerplugins-build: $(CLANGOUTDIR) $(CLANGOBJDIR) $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT)
155 compilerplugins-clean:
156 rm -rf \
157 $(CLANGOBJDIR) \
158 $(CLANGOUTDIR)/clang-timestamp \
159 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT) \
160 $(CLANGOUTDIR)/clang.pch{,.d} \
161 $(CLANGOUTDIR)/sharedvisitor/*.plugininfo \
162 $(CLANGOUTDIR)/sharedvisitor/clang.pch{,.d} \
163 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.{cxx,d,o} \
164 $(CLANGOUTDIR)/sharedvisitor/{analyzer,generator}{$(CLANG_EXE_EXT),.d,.o} \
165 $(CLANGOUTDIR)/sources-new.txt \
166 $(CLANGOUTDIR)/sources-shared-new.txt \
167 $(CLANGOUTDIR)/sources-shared.txt \
168 $(CLANGOUTDIR)/sources.txt
170 $(CLANGOUTDIR):
171 mkdir -p $(CLANGOUTDIR)
173 $(CLANGOBJDIR):
174 mkdir -p $(CLANGOBJDIR)
176 CLANGOBJS=
178 ifeq ($(OS),WNT)
180 # clangbuildsrc cxxfile objfile dfile
181 define clangbuildsrc
182 $(2): $(1) $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp
183 $$(call gb_Output_announce,$(subst $(SRCDIR)/,,$(subst $(BUILDDIR)/,,$(1))),$(true),CXX,3)
184 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
185 $(CLANGINCLUDES) /I$(BUILDDIR)/config_host /I$(CLANGINDIR) $(1) /MD \
186 /c /Fo: $(2)
188 -include $(3) #TODO
190 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(2)
191 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): CLANGOBJS += $(2)
192 endef
194 else
196 # clangbuildsrc cxxfile ofile dfile
197 define clangbuildsrc
198 $(2): $(1) $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp \
199 $(if $(LO_CLANG_USE_PCH),$(CLANGOUTDIR)/clang.pch)
200 $$(call gb_Output_announce,$(subst $(SRCDIR)/,,$(subst $(BUILDDIR)/,,$(1))),$(true),CXX,3)
201 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
202 $(CLANGINCLUDES) -I$(BUILDDIR)/config_host -I$(CLANGINDIR) $(1) \
203 $(if $(LO_CLANG_USE_PCH),-include-pch $(CLANGOUTDIR)/clang.pch -DPCH_LEVEL=$(gb_ENABLE_PCH)) \
204 -fPIC -c -o $(2) -MMD -MT $(2) -MP -MF $(3)
206 -include $(3)
208 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(2)
209 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): CLANGOBJS += $(2)
210 endef
212 endif
214 $(foreach src, $(CLANGSRCOUTDIR), $(eval $(call clangbuildsrc,$(src),$(src:.cxx=.o),$(src:.cxx=.d))))
215 $(foreach src, $(CLANGSRCINDIR), $(eval $(call clangbuildsrc,$(CLANGINDIR)/$(src),$(CLANGOBJDIR)/$(src:.cxx=.o),$(CLANGOBJDIR)/$(src:.cxx=.d))))
217 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(CLANGOBJS)
218 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),LNK,4)
219 ifeq ($(OS),WNT)
220 $(QUIET)$(COMPILER_PLUGINS_CXX) /LD $(CLANGOBJS) /Fe: $@ $(CLANGLIBDIR)/clang.lib \
221 mincore.lib version.lib /link $(COMPILER_PLUGINS_CXX_LINKFLAGS)
222 else
223 $(QUIET)$(COMPILER_PLUGINS_CXX) -shared $(CLANGOBJS) -o $@ \
224 $(if $(filter MACOSX,$(OS)),-Wl$(CLANG_COMMA)-flat_namespace \
225 -Wl$(CLANG_COMMA)-undefined -Wl$(CLANG_COMMA)suppress)
226 endif
228 # Clang most probably doesn't maintain binary compatibility, so rebuild when clang changes
229 # (either the binary can change if it's a local build, or config_clang.h will change if configure detects
230 # a new version of a newly installed system clang).
231 $(CLANGOUTDIR)/clang-timestamp: $(CLANGDIR)/bin/clang$(CLANG_EXE_EXT) $(BUILDDIR)/config_host/config_clang.h
232 $(QUIET)touch $@
235 ifdef LO_CLANG_SHARED_PLUGINS
236 SHARED_SOURCES := $(shell grep -l "LO_CLANG_SHARED_PLUGINS" $(CLANGINDIR)/*.cxx)
237 SHARED_SOURCE_INFOS := $(foreach source,$(SHARED_SOURCES),$(patsubst $(CLANGINDIR)/%.cxx,$(CLANGOUTDIR)/sharedvisitor/%.plugininfo,$(source)))
239 $(CLANGOUTDIR)/sharedvisitor/%.plugininfo: $(CLANGINDIR)/%.cxx \
240 $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT) \
241 $(CLANGOUTDIR)/sharedvisitor/clang.pch
242 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
243 $(QUIET)$(ICECREAM_RUN) $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT) \
244 $(COMPILER_PLUGINS_TOOLING_ARGS:%=-arg=%) $< > $@
246 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx: $(SHARED_SOURCE_INFOS) $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT)
247 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
248 $(QUIET)$(ICECREAM_RUN) $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT) \
249 $(SHARED_SOURCE_INFOS) > $@
251 # Flags used internally in analyzer.
252 # Older versions of Clang have a problem to find their own internal headers, so add it.
253 # Also filter out the c++ library, it's not necessary to be specific about it in this case
254 # and it can also cause trouble with finding the proper headers.
255 CLANGTOOLDEFS = $(filter-out -stdlib=%,$(CLANGDEFS) -I$(CLANGSYSINCLUDE))
256 CLANGTOOLDEFS += -w
257 ifneq ($(filter-out MACOSX WNT,$(OS)),)
258 ifneq ($(CLANGDIR),/usr)
259 # Help the generator find Clang shared libs, if Clang is built so and installed in a non-standard prefix.
260 CLANGTOOLLIBS += -Wl,--rpath,$(CLANGLIBDIR)
261 endif
262 endif
264 $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT): $(CLANGINDIR)/sharedvisitor/analyzer.cxx \
265 | $(CLANGOUTDIR)/sharedvisitor
266 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
267 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) $(CLANGINCLUDES) \
268 -I$(BUILDDIR)/config_host -DCLANGFLAGS='"$(CLANGTOOLDEFS)"' \
269 -DLO_CLANG_USE_ANALYZER_PCH=$(LO_CLANG_USE_ANALYZER_PCH) \
270 -c $< -o $(CLANGOUTDIR)/sharedvisitor/analyzer.o -MMD -MT $@ -MP \
271 -MF $(CLANGOUTDIR)/sharedvisitor/analyzer.d
272 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGOUTDIR)/sharedvisitor/analyzer.o \
273 -o $@ $(CLANGTOOLLIBS)
275 $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT): $(CLANGINDIR)/sharedvisitor/generator.cxx \
276 | $(CLANGOUTDIR)/sharedvisitor
277 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
278 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
279 -c $< -o $(CLANGOUTDIR)/sharedvisitor/generator.o -MMD -MT $@ -MP \
280 -MF $(CLANGOUTDIR)/sharedvisitor/generator.d
281 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGOUTDIR)/sharedvisitor/generator.o \
282 -o $@
284 $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT): $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp
286 $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT): $(SRCDIR)/compilerplugins/Makefile-clang.mk
288 $(CLANGOUTDIR)/sharedvisitor:
289 mkdir -p $(CLANGOUTDIR)/sharedvisitor
291 -include $(CLANGOUTDIR)/sharedvisitor/analyzer.d
292 -include $(CLANGOUTDIR)/sharedvisitor/generator.d
293 # TODO WNT version
295 # Remember the sources that are shared and if they have changed, force sharedvisitor.cxx generating.
296 # Duplicated from CLANGSRCCHANGED above.
297 CLANGSRCSHAREDCHANGED= \
298 $(shell mkdir -p $(CLANGOUTDIR) ; \
299 echo $(SHARED_SOURCES) | sort > $(CLANGOUTDIR)/sources-shared-new.txt; \
300 if diff $(CLANGOUTDIR)/sources-shared.txt $(CLANGOUTDIR)/sources-shared-new.txt >/dev/null 2>/dev/null; then \
301 echo 0; \
302 else \
303 mv $(CLANGOUTDIR)/sources-shared-new.txt $(CLANGOUTDIR)/sources-shared.txt; \
304 echo 1; \
305 fi; \
307 ifeq ($(CLANGSRCSHAREDCHANGED),1)
308 .PHONY: CLANGFORCE
309 CLANGFORCE:
310 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx: CLANGFORCE
311 endif
312 # Make sharedvisitor.cxx also explicitly depend on the sources list, to force update in case CLANGSRCSHAREDCHANGED was e.g. during 'make clean'.
313 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx: $(CLANGOUTDIR)/sources-shared.txt
314 $(CLANGOUTDIR)/sources-shared.txt:
315 touch $@
316 endif
318 ifneq ($(LO_CLANG_USE_PCH),)
319 # the PCH for plugin sources themselves
321 ifeq ($(OS),WNT)
322 # TODO
323 else
324 $(CLANGOUTDIR)/clang.pch: $(CLANGINDIR)/precompiled_clang.hxx \
325 $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp
326 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),PCH,1)
327 $(QUIET)$(COMPILER_PLUGINS_CXX) -x c++-header $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
328 $(CLANGINCLUDES) -I$(BUILDDIR)/config_host -I$(CLANGINDIR) -DPCH_LEVEL=$(gb_ENABLE_PCH) \
329 -fPIC -c $< -o $@ -MMD -MT $@ -MP -MF $(CLANGOUTDIR)/clang.pch.d
330 endif
331 -include $(CLANGOUTDIR)/clang.pch.d
333 endif
335 ifdef LO_CLANG_USE_ANALYZER_PCH
336 # the PCH for usage in sharedvisitor/analyzer
338 # these are from the invocation in analyzer.cxx
339 LO_CLANG_ANALYZER_PCH_CXXFLAGS := -I$(BUILDDIR)/config_host $(CLANGTOOLDEFS)
341 $(CLANGOUTDIR)/sharedvisitor/clang.pch: $(CLANGINDIR)/sharedvisitor/precompiled_clang.hxx \
342 $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp \
343 | $(CLANGOUTDIR)/sharedvisitor
344 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),PCH,1)
345 $(QUIET)$(CLANGDIR)/bin/clang -x c++-header $(LO_CLANG_ANALYZER_PCH_CXXFLAGS) \
346 $(COMPILER_PLUGINS_TOOLING_ARGS) -c $< -o $@ -MMD -MT $@ -MP \
347 -MF $(CLANGOUTDIR)/sharedvisitor/clang.pch.d
349 -include $(CLANGOUTDIR)/sharedvisitor/clang.pch.d
351 else
352 $(CLANGOUTDIR)/sharedvisitor/clang.pch:
353 touch $@
354 endif
356 # vim: set noet sw=4 ts=4: