tdf#161341 show/hide controls/shapes/pictures in view/print
[LibreOffice.git] / compilerplugins / Makefile-clang.mk
blob16a75e44b403f6a29d4159b70798cb1968364d78
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 -fvisibility-inlines-hidden
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 # The uninteresting rest.
52 include $(SRCDIR)/solenv/gbuild/gbuild.mk
53 include $(SRCDIR)/solenv/gbuild/Output.mk
55 CLANG_COMMA :=,
57 ifeq ($(OS),WNT)
58 CLANG_DL_EXT = .dll
59 CLANG_EXE_EXT = .exe
60 else
61 CLANG_DL_EXT = .so
62 CLANG_EXE_EXT =
63 endif
65 # Clang headers require these.
66 CLANGDEFS:=$(COMPILER_PLUGINS_CXXFLAGS)
67 # All include locations needed (using -isystem silences various warnings when
68 # including those files):
69 ifneq ($(OS),WNT)
70 CLANGDEFS:=$(filter-out -isystem/usr/include,$(foreach opt,$(CLANGDEFS),$(patsubst -I%,-isystem%,$(opt))))
71 endif
73 # Clang/LLVM libraries are intentionally not linked in, they are usually built as static libraries, which means the resulting
74 # plugin would be big (even though the clang binary already includes it all) and it'd be necessary to explicitly specify
75 # also all the dependency libraries.
77 CLANGINDIR=$(SRCDIR)/compilerplugins/clang
78 # Cannot use $(WORKDIR), the plugin should survive even 'make clean', otherwise the rebuilt
79 # plugin will cause cache misses with ccache.
80 CLANGOUTDIR=$(BUILDDIR)/compilerplugins/clang
81 CLANGOBJDIR=$(CLANGOUTDIR)/obj
83 ifdef LO_CLANG_SHARED_PLUGINS
84 CLANGCXXFLAGS+=-DLO_CLANG_SHARED_PLUGINS
85 endif
87 ifneq ($(CLANGDEBUG),)
88 ifeq ($(HAVE_GCC_SPLIT_DWARF),TRUE)
89 CLANGCXXFLAGS+=-gsplit-dwarf
90 endif
91 endif
93 QUIET=$(if $(verbose),,@)
95 ifneq ($(ENABLE_WERROR),)
96 ifeq ($(OS),WNT)
97 CLANGWERROR :=
98 #TODO: /WX
99 else
100 CLANGWERROR := -Werror
101 # When COMPILER_PLUGINS_CXXFLAGS (obtained via `llvm-config --cxxflags`) contains options like
102 # -Wno-maybe-uninitialized that are targeting GCC (when LLVM was actually built with GCC), and
103 # COMPILER_PLUGINS_CXX (defaulting to CXX) denotes a Clang that does not understand those options,
104 # it fails with -Werror,-Wunknown-warning-option, so we need -Wno-unknown-warning-option (but which
105 # GCC does not understand) at least with -Werror:
106 ifeq ($(COMPILER_PLUGINS_COM_IS_CLANG),TRUE)
107 CLANGWERROR += -Wno-unknown-warning-option
108 endif
109 endif
110 endif
112 ifneq ($(LO_CLANG_USE_PCH),)
113 # Reset and enable only if actually supported and enabled.
114 LO_CLANG_USE_PCH=
115 ifneq ($(gb_ENABLE_PCH),)
116 ifneq ($(OS),WNT)
117 # Currently only Clang PCH is supported (which should usually be the case, as Clang is usually self-built).
118 ifneq ($(findstring clang,$(COMPILER_PLUGINS_CXX)),)
119 LO_CLANG_USE_PCH=1
120 LO_CLANG_PCH_FLAGS:=-Xclang -fno-pch-timestamp
121 endif
122 endif
123 endif
124 endif
127 compilerplugins: compilerplugins-build
129 ifdef LO_CLANG_SHARED_PLUGINS
130 # The shared source, intentionally put first in the list because it takes the longest to build.
131 CLANGSRCOUTDIR=$(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx
132 CLANGSRC+=$(CLANGSRCOUTDIR)
133 endif
134 # The list of source files, generated automatically (all files in clang/, but not subdirs).
135 CLANGSRCINDIR=$(sort $(foreach src,$(wildcard $(CLANGINDIR)/*.cxx), $(notdir $(src))))
136 CLANGSRC+=$(CLANGSRCINDIR)
138 # Remember the sources and if they have changed, force plugin relinking.
139 CLANGSRCCHANGED= \
140 $(shell mkdir -p $(CLANGOUTDIR) ; \
141 echo $(CLANGSRC) | sort > $(CLANGOUTDIR)/sources-new.txt; \
142 if diff $(CLANGOUTDIR)/sources.txt $(CLANGOUTDIR)/sources-new.txt >/dev/null 2>/dev/null; then \
143 echo 0; \
144 else \
145 mv $(CLANGOUTDIR)/sources-new.txt $(CLANGOUTDIR)/sources.txt; \
146 echo 1; \
147 fi; \
149 ifeq ($(CLANGSRCCHANGED),1)
150 .PHONY: CLANGFORCE
151 CLANGFORCE:
152 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): CLANGFORCE
153 endif
154 # Make the .so also explicitly depend on the sources list, to force update in case CLANGSRCCHANGED was e.g. during 'make clean'.
155 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(CLANGOUTDIR)/sources.txt
156 $(CLANGOUTDIR)/sources.txt:
157 touch $@
159 compilerplugins-build: $(CLANGOUTDIR) $(CLANGOBJDIR) $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT)
161 compilerplugins-clean:
162 rm -rf \
163 $(CLANGOBJDIR) \
164 $(CLANGOUTDIR)/clang-timestamp \
165 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT) \
166 $(CLANGOUTDIR)/clang.pch{,.d} \
167 $(CLANGOUTDIR)/sharedvisitor/*.plugininfo \
168 $(CLANGOUTDIR)/sharedvisitor/clang.pch{,.d} \
169 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.{cxx,d,o} \
170 $(CLANGOUTDIR)/sharedvisitor/{analyzer,generator}{$(CLANG_EXE_EXT),.d,.o} \
171 $(CLANGOUTDIR)/sources-new.txt \
172 $(CLANGOUTDIR)/sources-shared-new.txt \
173 $(CLANGOUTDIR)/sources-shared.txt \
174 $(CLANGOUTDIR)/sources.txt
176 $(CLANGOUTDIR):
177 mkdir -p $(CLANGOUTDIR)
179 $(CLANGOBJDIR):
180 mkdir -p $(CLANGOBJDIR)
182 CLANGOBJS=
184 ifeq ($(OS),WNT)
186 # clangbuildsrc cxxfile objfile dfile
187 define clangbuildsrc
188 $(2): $(1) $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp
189 $$(call gb_Output_announce,$(subst $(SRCDIR)/,,$(subst $(BUILDDIR)/,,$(1))),$(true),CXX,3)
190 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
191 $(CLANGINCLUDES) /I$(BUILDDIR)/config_host /I$(CLANGINDIR) $(1) /MD \
192 /c /Fo: $(2)
194 -include $(3) #TODO
196 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(2)
197 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): CLANGOBJS += $(2)
198 endef
200 else
202 # clangbuildsrc cxxfile ofile dfile
203 define clangbuildsrc
204 $(2): $(1) $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp \
205 $(if $(LO_CLANG_USE_PCH),$(CLANGOUTDIR)/clang.pch)
206 $$(call gb_Output_announce,$(subst $(SRCDIR)/,,$(subst $(BUILDDIR)/,,$(1))),$(true),CXX,3)
207 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
208 $(CLANGINCLUDES) -I$(BUILDDIR)/config_host -I$(CLANGINDIR) $(1) \
209 $(if $(LO_CLANG_USE_PCH),-include-pch $(CLANGOUTDIR)/clang.pch -DPCH_LEVEL=$(gb_ENABLE_PCH)) \
210 -fPIC -c -o $(2) -MMD -MT $(2) -MP -MF $(3)
212 -include $(3)
214 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(2)
215 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): CLANGOBJS += $(2)
216 endef
218 endif
220 $(foreach src, $(CLANGSRCOUTDIR), $(eval $(call clangbuildsrc,$(src),$(src:.cxx=.o),$(src:.cxx=.d))))
221 $(foreach src, $(CLANGSRCINDIR), $(eval $(call clangbuildsrc,$(CLANGINDIR)/$(src),$(CLANGOBJDIR)/$(src:.cxx=.o),$(CLANGOBJDIR)/$(src:.cxx=.d))))
223 $(CLANGOUTDIR)/plugin$(CLANG_DL_EXT): $(CLANGOBJS)
224 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),LNK,4)
225 ifeq ($(OS),WNT)
226 $(QUIET)$(COMPILER_PLUGINS_CXX) /LD $(CLANGOBJS) /Fe: $@ $(CLANGLIBDIR)/clang.lib \
227 mincore.lib version.lib /link $(COMPILER_PLUGINS_CXX_LINKFLAGS)
228 else
229 $(QUIET)$(COMPILER_PLUGINS_CXX) -shared $(CLANGOBJS) -o $@ \
230 $(if $(filter MACOSX,$(OS)),-Wl$(CLANG_COMMA)-flat_namespace \
231 -Wl$(CLANG_COMMA)-undefined -Wl$(CLANG_COMMA)suppress)
232 endif
234 # Clang most probably doesn't maintain binary compatibility, so rebuild when clang changes
235 # (either the binary can change if it's a local build, or config_clang.h will change if configure detects
236 # a new version of a newly installed system clang).
237 $(CLANGOUTDIR)/clang-timestamp: $(CLANGDIR)/bin/clang$(CLANG_EXE_EXT) $(BUILDDIR)/config_host/config_clang.h
238 $(QUIET)touch $@
241 ifdef LO_CLANG_SHARED_PLUGINS
242 SHARED_SOURCES := $(sort $(shell grep -l "LO_CLANG_SHARED_PLUGINS" $(CLANGINDIR)/*.cxx))
243 SHARED_SOURCE_INFOS := $(foreach source,$(SHARED_SOURCES),$(patsubst $(CLANGINDIR)/%.cxx,$(CLANGOUTDIR)/sharedvisitor/%.plugininfo,$(source)))
245 $(CLANGOUTDIR)/sharedvisitor/%.plugininfo: $(CLANGINDIR)/%.cxx \
246 $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT) \
247 $(CLANGOUTDIR)/sharedvisitor/clang.pch
248 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
249 $(QUIET)$(ICECREAM_RUN) $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT) \
250 $(COMPILER_PLUGINS_TOOLING_ARGS:%=-arg=%) $< > $@
252 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx: $(SHARED_SOURCE_INFOS) $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT)
253 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
254 $(QUIET)$(ICECREAM_RUN) $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT) \
255 $(SHARED_SOURCE_INFOS) > $@
257 # Flags used internally in analyzer.
258 # Older versions of Clang have a problem to find their own internal headers, so add it.
259 # Also filter out the c++ library, it's not necessary to be specific about it in this case
260 # and it can also cause trouble with finding the proper headers.
261 CLANGTOOLDEFS = $(filter-out -stdlib=%,$(CLANGDEFS) -I$(CLANGSYSINCLUDE))
262 CLANGTOOLDEFS += -w
263 ifneq ($(filter MACOSX,$(OS)),)
264 CLANGTOOLLIBS += -Wl,-rpath,$(CLANGLIBDIR)
265 else ifneq ($(filter-out WNT,$(OS)),)
266 ifneq ($(CLANGDIR),/usr)
267 # Help the generator find Clang shared libs, if Clang is built so and installed in a non-standard prefix.
268 CLANGTOOLLIBS += -Wl,--rpath,$(CLANGLIBDIR)
269 endif
270 endif
272 $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT): $(CLANGINDIR)/sharedvisitor/analyzer.cxx \
273 | $(CLANGOUTDIR)/sharedvisitor
274 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
275 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) $(CLANGINCLUDES) \
276 -I$(BUILDDIR)/config_host -DCLANGFLAGS='"$(CLANGTOOLDEFS)"' \
277 -DLO_CLANG_USE_ANALYZER_PCH=$(if $(COMPILER_PLUGINS_ANALYZER_PCH),1,0) \
278 -c $< -o $(CLANGOUTDIR)/sharedvisitor/analyzer.o -MMD -MT $@ -MP \
279 -MF $(CLANGOUTDIR)/sharedvisitor/analyzer.d
280 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGOUTDIR)/sharedvisitor/analyzer.o \
281 -o $@ $(CLANGTOOLLIBS)
283 $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT): $(CLANGINDIR)/sharedvisitor/generator.cxx \
284 | $(CLANGOUTDIR)/sharedvisitor
285 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),GEN,1)
286 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
287 -c $< -o $(CLANGOUTDIR)/sharedvisitor/generator.o -MMD -MT $@ -MP \
288 -MF $(CLANGOUTDIR)/sharedvisitor/generator.d
289 $(QUIET)$(COMPILER_PLUGINS_CXX) $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGOUTDIR)/sharedvisitor/generator.o \
290 -o $@
292 $(CLANGOUTDIR)/sharedvisitor/analyzer$(CLANG_EXE_EXT): $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp
294 $(CLANGOUTDIR)/sharedvisitor/generator$(CLANG_EXE_EXT): $(SRCDIR)/compilerplugins/Makefile-clang.mk
296 $(CLANGOUTDIR)/sharedvisitor:
297 mkdir -p $(CLANGOUTDIR)/sharedvisitor
299 -include $(CLANGOUTDIR)/sharedvisitor/analyzer.d
300 -include $(CLANGOUTDIR)/sharedvisitor/generator.d
301 # TODO WNT version
303 # Remember the sources that are shared and if they have changed, force sharedvisitor.cxx generating.
304 # Duplicated from CLANGSRCCHANGED above.
305 CLANGSRCSHAREDCHANGED= \
306 $(shell mkdir -p $(CLANGOUTDIR) ; \
307 echo $(SHARED_SOURCES) | sort > $(CLANGOUTDIR)/sources-shared-new.txt; \
308 if diff $(CLANGOUTDIR)/sources-shared.txt $(CLANGOUTDIR)/sources-shared-new.txt >/dev/null 2>/dev/null; then \
309 echo 0; \
310 else \
311 mv $(CLANGOUTDIR)/sources-shared-new.txt $(CLANGOUTDIR)/sources-shared.txt; \
312 echo 1; \
313 fi; \
315 ifeq ($(CLANGSRCSHAREDCHANGED),1)
316 .PHONY: CLANGFORCE
317 CLANGFORCE:
318 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx: CLANGFORCE
319 endif
320 # Make sharedvisitor.cxx also explicitly depend on the sources list, to force update in case CLANGSRCSHAREDCHANGED was e.g. during 'make clean'.
321 $(CLANGOUTDIR)/sharedvisitor/sharedvisitor.cxx: $(CLANGOUTDIR)/sources-shared.txt
322 $(CLANGOUTDIR)/sources-shared.txt:
323 touch $@
324 endif
326 ifneq ($(LO_CLANG_USE_PCH),)
327 # the PCH for plugin sources themselves
329 ifeq ($(OS),WNT)
330 # TODO
331 else
332 $(CLANGOUTDIR)/clang.pch: $(CLANGINDIR)/precompiled_clang.hxx \
333 $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp
334 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),PCH,1)
335 $(QUIET)$(COMPILER_PLUGINS_CXX) -x c++-header $(CLANGDEFS) $(CLANGCXXFLAGS) $(CLANGWERROR) \
336 $(CLANGINCLUDES) -I$(BUILDDIR)/config_host -I$(CLANGINDIR) -DPCH_LEVEL=$(gb_ENABLE_PCH) \
337 $(LO_CLANG_PCH_FLAGS) \
338 -fPIC -c $< -o $@ -MMD -MT $@ -MP -MF $(CLANGOUTDIR)/clang.pch.d
339 endif
340 -include $(CLANGOUTDIR)/clang.pch.d
342 endif
344 ifeq ($(COMPILER_PLUGINS_ANALYZER_PCH),TRUE)
345 # the PCH for usage in sharedvisitor/analyzer
347 # these are from the invocation in analyzer.cxx
348 LO_CLANG_ANALYZER_PCH_CXXFLAGS := -I$(BUILDDIR)/config_host $(CLANGTOOLDEFS)
350 $(CLANGOUTDIR)/sharedvisitor/clang.pch: $(CLANGINDIR)/sharedvisitor/precompiled_clang.hxx \
351 $(SRCDIR)/compilerplugins/Makefile-clang.mk $(CLANGOUTDIR)/clang-timestamp \
352 | $(CLANGOUTDIR)/sharedvisitor
353 $(call gb_Output_announce,$(subst $(BUILDDIR)/,,$@),$(true),PCH,1)
354 $(QUIET)$(CLANGDIR)/bin/clang -x c++-header $(LO_CLANG_ANALYZER_PCH_CXXFLAGS) \
355 $(LO_CLANG_PCH_FLAGS) $(COMPILER_PLUGINS_TOOLING_ARGS) -c $< -o $@ -MMD -MT $@ -MP \
356 -MF $(CLANGOUTDIR)/sharedvisitor/clang.pch.d
358 -include $(CLANGOUTDIR)/sharedvisitor/clang.pch.d
360 else
361 $(CLANGOUTDIR)/sharedvisitor/clang.pch:
362 touch $@
363 endif
365 # vim: set noet sw=4 ts=4: