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).
14 # Compile flags, you may occasionally want to override these:
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-
24 CLANGCXXFLAGS
+=/O2
/Oi
26 CLANGCXXFLAGS
+=/DEBUG
/Od
29 CLANGCXXFLAGS
=-Wall
-Wextra
-Wundef
-fvisibility-inlines-hidden
33 CLANGCXXFLAGS
+=-g
-O0
-UNDEBUG
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
43 LO_CLANG_SHARED_PLUGINS
=
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.
50 # The uninteresting rest.
52 include $(SRCDIR
)/solenv
/gbuild
/gbuild.mk
53 include $(SRCDIR
)/solenv
/gbuild
/Output.mk
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):
70 CLANGDEFS
:=$(filter-out -isystem
/usr
/include,$(foreach opt
,$(CLANGDEFS
),$(patsubst -I
%,-isystem
%,$(opt
))))
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
87 ifneq ($(CLANGDEBUG
),)
88 ifeq ($(HAVE_GCC_SPLIT_DWARF
),TRUE
)
89 CLANGCXXFLAGS
+=-gsplit-dwarf
93 QUIET
=$(if
$(verbose
),,@
)
95 ifneq ($(ENABLE_WERROR
),)
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
112 ifneq ($(LO_CLANG_USE_PCH
),)
113 # Reset and enable only if actually supported and enabled.
115 ifneq ($(gb_ENABLE_PCH
),)
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
)),)
120 LO_CLANG_PCH_FLAGS
:=-Xclang
-fno-pch-timestamp
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
)
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.
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 \
145 mv
$(CLANGOUTDIR
)/sources-new.txt
$(CLANGOUTDIR
)/sources.txt
; \
149 ifeq ($(CLANGSRCCHANGED
),1)
152 $(CLANGOUTDIR
)/plugin
$(CLANG_DL_EXT
): CLANGFORCE
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
:
159 compilerplugins-build
: $(CLANGOUTDIR
) $(CLANGOBJDIR
) $(CLANGOUTDIR
)/plugin
$(CLANG_DL_EXT
)
161 compilerplugins-clean
:
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
177 mkdir
-p
$(CLANGOUTDIR
)
180 mkdir
-p
$(CLANGOBJDIR
)
186 # clangbuildsrc cxxfile objfile dfile
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 \
196 $(CLANGOUTDIR
)/plugin
$(CLANG_DL_EXT
): $(2)
197 $(CLANGOUTDIR
)/plugin
$(CLANG_DL_EXT
): CLANGOBJS
+= $(2)
202 # clangbuildsrc cxxfile ofile dfile
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)
214 $(CLANGOUTDIR
)/plugin
$(CLANG_DL_EXT
): $(2)
215 $(CLANGOUTDIR
)/plugin
$(CLANG_DL_EXT
): CLANGOBJS
+= $(2)
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)
226 $(QUIET
)$(COMPILER_PLUGINS_CXX
) /LD
$(CLANGOBJS
) /Fe
: $@
$(CLANGLIBDIR
)/clang.lib \
227 mincore.lib version.lib
/link
$(COMPILER_PLUGINS_CXX_LINKFLAGS
)
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
)
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
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
))
263 ifneq ($(filter-out MACOSX WNT
,$(OS
)),)
264 ifneq ($(CLANGDIR
),/usr
)
265 # Help the generator find Clang shared libs, if Clang is built so and installed in a non-standard prefix.
266 CLANGTOOLLIBS
+= -Wl
,--rpath
,$(CLANGLIBDIR
)
270 $(CLANGOUTDIR
)/sharedvisitor
/analyzer
$(CLANG_EXE_EXT
): $(CLANGINDIR
)/sharedvisitor
/analyzer.
cxx \
271 |
$(CLANGOUTDIR
)/sharedvisitor
272 $(call gb_Output_announce
,$(subst $(BUILDDIR
)/,,$@
),$(true
),GEN
,1)
273 $(QUIET
)$(COMPILER_PLUGINS_CXX
) $(CLANGDEFS
) $(CLANGCXXFLAGS
) $(CLANGWERROR
) $(CLANGINCLUDES
) \
274 -I
$(BUILDDIR
)/config_host
-DCLANGFLAGS
='"$(CLANGTOOLDEFS)"' \
275 -DLO_CLANG_USE_ANALYZER_PCH
=$(if
$(COMPILER_PLUGINS_ANALYZER_PCH
),1,0) \
276 -c
$< -o
$(CLANGOUTDIR
)/sharedvisitor
/analyzer.o
-MMD
-MT
$@
-MP \
277 -MF
$(CLANGOUTDIR
)/sharedvisitor
/analyzer.d
278 $(QUIET
)$(COMPILER_PLUGINS_CXX
) $(CLANGDEFS
) $(CLANGCXXFLAGS
) $(CLANGOUTDIR
)/sharedvisitor
/analyzer.o \
279 -o
$@
$(CLANGTOOLLIBS
)
281 $(CLANGOUTDIR
)/sharedvisitor
/generator
$(CLANG_EXE_EXT
): $(CLANGINDIR
)/sharedvisitor
/generator.
cxx \
282 |
$(CLANGOUTDIR
)/sharedvisitor
283 $(call gb_Output_announce
,$(subst $(BUILDDIR
)/,,$@
),$(true
),GEN
,1)
284 $(QUIET
)$(COMPILER_PLUGINS_CXX
) $(CLANGDEFS
) $(CLANGCXXFLAGS
) $(CLANGWERROR
) \
285 -c
$< -o
$(CLANGOUTDIR
)/sharedvisitor
/generator.o
-MMD
-MT
$@
-MP \
286 -MF
$(CLANGOUTDIR
)/sharedvisitor
/generator.d
287 $(QUIET
)$(COMPILER_PLUGINS_CXX
) $(CLANGDEFS
) $(CLANGCXXFLAGS
) $(CLANGOUTDIR
)/sharedvisitor
/generator.o \
290 $(CLANGOUTDIR
)/sharedvisitor
/analyzer
$(CLANG_EXE_EXT
): $(SRCDIR
)/compilerplugins
/Makefile-clang.mk
$(CLANGOUTDIR
)/clang-timestamp
292 $(CLANGOUTDIR
)/sharedvisitor
/generator
$(CLANG_EXE_EXT
): $(SRCDIR
)/compilerplugins
/Makefile-clang.mk
294 $(CLANGOUTDIR
)/sharedvisitor
:
295 mkdir
-p
$(CLANGOUTDIR
)/sharedvisitor
297 -include $(CLANGOUTDIR
)/sharedvisitor
/analyzer.d
298 -include $(CLANGOUTDIR
)/sharedvisitor
/generator.d
301 # Remember the sources that are shared and if they have changed, force sharedvisitor.cxx generating.
302 # Duplicated from CLANGSRCCHANGED above.
303 CLANGSRCSHAREDCHANGED
= \
304 $(shell mkdir
-p
$(CLANGOUTDIR
) ; \
305 echo
$(SHARED_SOURCES
) |
sort > $(CLANGOUTDIR
)/sources-shared-new.txt
; \
306 if diff
$(CLANGOUTDIR
)/sources-shared.txt
$(CLANGOUTDIR
)/sources-shared-new.txt
>/dev
/null
2>/dev
/null
; then \
309 mv
$(CLANGOUTDIR
)/sources-shared-new.txt
$(CLANGOUTDIR
)/sources-shared.txt
; \
313 ifeq ($(CLANGSRCSHAREDCHANGED
),1)
316 $(CLANGOUTDIR
)/sharedvisitor
/sharedvisitor.
cxx: CLANGFORCE
318 # Make sharedvisitor.cxx also explicitly depend on the sources list, to force update in case CLANGSRCSHAREDCHANGED was e.g. during 'make clean'.
319 $(CLANGOUTDIR
)/sharedvisitor
/sharedvisitor.
cxx: $(CLANGOUTDIR
)/sources-shared.txt
320 $(CLANGOUTDIR
)/sources-shared.txt
:
324 ifneq ($(LO_CLANG_USE_PCH
),)
325 # the PCH for plugin sources themselves
330 $(CLANGOUTDIR
)/clang.pch
: $(CLANGINDIR
)/precompiled_clang.hxx \
331 $(SRCDIR
)/compilerplugins
/Makefile-clang.mk
$(CLANGOUTDIR
)/clang-timestamp
332 $(call gb_Output_announce
,$(subst $(BUILDDIR
)/,,$@
),$(true
),PCH
,1)
333 $(QUIET
)$(COMPILER_PLUGINS_CXX
) -x c
++-header
$(CLANGDEFS
) $(CLANGCXXFLAGS
) $(CLANGWERROR
) \
334 $(CLANGINCLUDES
) -I
$(BUILDDIR
)/config_host
-I
$(CLANGINDIR
) -DPCH_LEVEL
=$(gb_ENABLE_PCH
) \
335 $(LO_CLANG_PCH_FLAGS
) \
336 -fPIC
-c
$< -o
$@
-MMD
-MT
$@
-MP
-MF
$(CLANGOUTDIR
)/clang.pch.d
338 -include $(CLANGOUTDIR
)/clang.pch.d
342 ifeq ($(COMPILER_PLUGINS_ANALYZER_PCH
),TRUE
)
343 # the PCH for usage in sharedvisitor/analyzer
345 # these are from the invocation in analyzer.cxx
346 LO_CLANG_ANALYZER_PCH_CXXFLAGS
:= -I
$(BUILDDIR
)/config_host
$(CLANGTOOLDEFS
)
348 $(CLANGOUTDIR
)/sharedvisitor
/clang.pch
: $(CLANGINDIR
)/sharedvisitor
/precompiled_clang.hxx \
349 $(SRCDIR
)/compilerplugins
/Makefile-clang.mk
$(CLANGOUTDIR
)/clang-timestamp \
350 |
$(CLANGOUTDIR
)/sharedvisitor
351 $(call gb_Output_announce
,$(subst $(BUILDDIR
)/,,$@
),$(true
),PCH
,1)
352 $(QUIET
)$(CLANGDIR
)/bin
/clang
-x c
++-header
$(LO_CLANG_ANALYZER_PCH_CXXFLAGS
) \
353 $(LO_CLANG_PCH_FLAGS
) $(COMPILER_PLUGINS_TOOLING_ARGS
) -c
$< -o
$@
-MMD
-MT
$@
-MP \
354 -MF
$(CLANGOUTDIR
)/sharedvisitor
/clang.pch.d
356 -include $(CLANGOUTDIR
)/sharedvisitor
/clang.pch.d
359 $(CLANGOUTDIR
)/sharedvisitor
/clang.pch
:
363 # vim: set noet sw=4 ts=4: