1 # -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 # This file incorporates work covered by the following license notice:
11 # Licensed to the Apache Software Foundation (ASF) under one or more
12 # contributor license agreements. See the NOTICE file distributed
13 # with this work for additional information regarding copyright
14 # ownership. The ASF licenses this file to you under the Apache
15 # License, Version 2.0 (the "License"); you may not use this file
16 # except in compliance with the License. You may obtain a copy of
17 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 # to block heavy exception handling that try to acquire the solarmutex
21 export LO_LEAN_EXCEPTION
=1
23 include $(GBUILDDIR
)/platform
/com_GCC_defs.mk
25 gb_MKTEMP
:= mktemp
-t gbuild.XXXXXX
27 ifneq ($(origin AR
),default
)
44 # At least libstdc++ needs -pthread when including various C++ headers like <thread>, see
45 # <https://gcc.gnu.org/onlinedocs/gcc-8.3.0/libstdc++/manual/manual/using.html
46 # #manual.intro.using.flags>:
47 ifneq ($(HAVE_LIBSTDCPP
),)
48 gb_CXX_LINKFLAGS
:= -pthread
51 ifneq ($(HAVE_LIBCPP
),)
52 gb_CXX_LINKFLAGS
:= -pthread
56 $(gb_CXXFLAGS_COMMON
) \
59 -Woverloaded-virtual \
64 ifneq ($(strip $(SYSBASE
)),)
65 gb_CXXFLAGS
+= --sysroot
=$(SYSBASE
)
66 gb_CFLAGS
+= --sysroot
=$(SYSBASE
)
67 gb_LinkTarget_LDFLAGS
+= \
68 -Wl
,--sysroot
=$(SYSBASE
)
71 ifeq (,$(DISABLE_DYNLOADING
))
72 gb_LinkTarget_LDFLAGS
+= \
73 -Wl
,-rpath-link
,$(SYSBASE
)/lib
:$(SYSBASE
)/usr
/lib \
78 ifeq ($(HAVE_LD_HASH_STYLE
),TRUE
)
79 gb_LinkTarget_LDFLAGS
+= \
80 -Wl
,--hash-style
=$(WITH_LINKER_HASH_STYLE
) \
84 ifneq ($(HAVE_LD_BSYMBOLIC_FUNCTIONS
),)
85 gb_LinkTarget_LDFLAGS
+= -Wl
,-Bsymbolic-functions
88 gb_LINKEROPTFLAGS
:= -Wl
,-O1
89 gb_LINKERSTRIPDEBUGFLAGS
:= -Wl
,-S
93 define gb_LinkTarget__get_rpath_for_layer
94 $(patsubst $(1):%,%,$(filter $(1):%,$(gb_LinkTarget__RPATHS
)))
97 gb_LinkTarget__RPATHS
:= \
101 SDKBIN
:\dORIGIN
/..
/..
/program \
103 NONE
:\dORIGIN
/..
/Library \
105 gb_LinkTarget_CFLAGS
:= $(gb_CFLAGS
)
106 gb_LinkTarget_CXXFLAGS
:= $(gb_CXXFLAGS
)
108 gb_LinkTarget__cmd_lockfile
= $(if
$(LOCKFILE
),$(LOCKFILE
),$(call gb_Executable_get_command
,lockfile
))
109 gb_LinkTarget__Lock
:= $(WORKDIR
)/LinkTarget
/link.lock
111 # No newline or space before endef!
112 define gb_LinkTarget__WantLock
114 $(call gb_CondExeLockfile
,$(true
)), \
115 $(filter-out Executable
/lockfile
,$(1)), \
116 $(if
$(filter FUZZERS
,$(BUILD_TYPE
)),,$(DISABLE_DYNLOADING
)), \
117 $(filter CppunitTest Executable
,$(TARGETTYPE
)) \
121 # In theory would need to track, if any of the linked objects is C++ code, so for the static build we assume yes :-(
122 gb_LinkTarget__NeedsCxxLinker
= $(if
$(CXXOBJECTS
)$(GENCXXOBJECTS
)$(EXTRAOBJECTLISTS
)$(filter-out XTRUE
,X
$(ENABLE_RUNTIME_OPTIMIZATIONS
)$(DISABLE_DYNLOADING
)),$(true
))
124 # note that `cat $(extraobjectlist)` is needed to build with older gcc versions, e.g. 4.1.2 on SLED10
125 # we want to use @$(extraobjectlist) in the long run
126 # link with C compiler if there are no C++ files (pyuno_wrapper depends on this)
127 # But always link with C++ compiler e.g. under -fsanitize=undefined, as sal uses
128 # __ubsan_handle_dynamic_type_cache_miss_abort and __ubsan_vptr_type_cache from
129 # libclang_rt.ubsan_cxx-x86_64.a, and oosplash links against sal but itself only
130 # contains .c sources:
131 define gb_LinkTarget__command_dynamiclink
132 $(if
$(call gb_LinkTarget__WantLock
,$2), \
133 echo
"$(call gb_Output_announce_str,$(2): wait for lock at $$(date -u),$(true),LNK,5)" ; \
134 $(gb_LinkTarget__cmd_lockfile
) -r
-1 $(gb_LinkTarget__Lock
) ; \
135 echo
"$(call gb_Output_announce_str,$(2): got link lock at $$(date -u),$(true),LNK,5)" ; \
137 +$(if
$(filter EMSCRIPTEN
,$(OS
)),unset PYTHONWARNINGS
;) \
138 $(call gb_Helper_abbreviate_dirs
,\
139 $(if
$(call gb_LinkTarget__NeedsCxxLinker
),$(or
$(T_CXX
),$(gb_CXX
)) $(gb_CXX_LINKFLAGS
),$(or
$(T_CC
),$(gb_CC
))) \
140 $(if
$(filter Library CppunitTest
,$(TARGETTYPE
)),$(gb_Library_TARGETTYPEFLAGS
)) \
142 $(if
$(SOVERSIONSCRIPT
),-Wl
$(COMMA
)--soname
=$(notdir $(1)) \
143 -Wl
$(COMMA
)--version-script
=$(SOVERSIONSCRIPT
)) \
144 $(subst \d
,$$,$(RPATH
)) \
145 $(T_USE_LD
) $(T_LDFLAGS
) $(foreach pre_js
,$(T_PREJS
), --pre-js
$(pre_js
)) \
146 $(foreach object
,$(COBJECTS
),$(call gb_CObject_get_target
,$(object
))) \
147 $(foreach object
,$(CXXOBJECTS
),$(call gb_CxxObject_get_target
,$(object
))) \
148 $(foreach object
,$(ASMOBJECTS
),$(call gb_AsmObject_get_target
,$(object
))) \
149 $(foreach object
,$(GENCOBJECTS
),$(call gb_GenCObject_get_target
,$(object
))) \
150 $(foreach object
,$(GENCXXOBJECTS
),$(call gb_GenCxxObject_get_target
,$(object
))) \
151 $(foreach object
,$(GENNASMOBJECTS
),$(call gb_GenNasmObject_get_target
,$(object
))) \
152 $(foreach extraobjectlist
,$(EXTRAOBJECTLISTS
),`cat $(extraobjectlist)`) \
153 $(if
$(filter TRUE
,$(DISABLE_DYNLOADING
)), \
154 -Wl
$(COMMA
)--start-group \
156 $(patsubst lib
%.a
,-l
%,$(patsubst lib
%.so
,-l
%,$(patsubst %.
$(gb_Library_UDK_MAJORVER
),%,$(foreach lib
,$(LINKED_LIBS
),$(call gb_Library_get_filename
,$(lib
)))))) \
157 $(foreach lib
,$(LINKED_STATIC_LIBS
),$(call gb_StaticLibrary_get_target
,$(lib
))) \
158 $(patsubst $(gb_LinkTarget__syslib
),%,$(T_LIBS
)) \
159 $(if
$(call gb_LinkTarget__NeedsCxxLinker
),$(T_STDLIBS_CXX
)) \
161 -Wl
$(COMMA
)--end-group \
163 -Wl
$(COMMA
)--start-group \
164 $(foreach lib
,$(LINKED_STATIC_LIBS
),$(call gb_StaticLibrary_get_target
,$(lib
))) \
166 $(if
$(call gb_LinkTarget__NeedsCxxLinker
),$(T_STDLIBS_CXX
)) \
167 -Wl
$(COMMA
)--end-group \
168 -Wl
$(COMMA
)--no-as-needed \
169 $(patsubst lib
%.a
,-l
%,$(patsubst lib
%.so
,-l
%,$(patsubst %.
$(gb_Library_UDK_MAJORVER
),%,$(foreach lib
,$(LINKED_LIBS
),$(call gb_Library_get_filename
,$(lib
)))))) \
172 $(if
$(SOVERSIONSCRIPT
),&& ln
-sf ..
/..
/program
/$(notdir $(1)) $(ILIBTARGET
)) \
173 $(if
$(call gb_LinkTarget__WantLock
,$(2)),; RC
=$$?
; rm -f
$(gb_LinkTarget__Lock
); if
test $$RC -ne
0; then exit
$$RC; fi
))
175 $(if
$(filter Library
,$(TARGETTYPE
)), $(call gb_Helper_abbreviate_dirs
,\
176 $(READELF
) -d
$(1) | grep SONAME
> $(WORKDIR
)/LinkTarget
/$(2).exports.tmp
; \
177 $(NM
) $(gb_LTOPLUGINFLAGS
) --dynamic
--extern-only
--defined-only
--format
=posix
$(1) \
178 | cut
-d
' ' -f1-2
>> $(WORKDIR
)/LinkTarget
/$(2).exports.tmp
&& \
179 $(call gb_Helper_replace_if_different_and_touch
,$(WORKDIR
)/LinkTarget
/$(2).exports.tmp
, \
180 $(WORKDIR
)/LinkTarget
/$(2).exports
,$(1))))
181 $(if
$(and
$(filter CppunitTest Executable
,$(TARGETTYPE
)),$(filter EMSCRIPTEN
,$(OS
))), \
182 $(if
$(filter TRUE
,$(ENABLE_QT5
)), \
183 sed
-e
's/@APPNAME@/$(subst $(gb_Executable_EXT),,$(notdir $(1)))/' $(QT5_PLATFORMS_SRCDIR
)/wasm_shell.html
> $(dir $(1))qt_
$(notdir $(1)); \
184 cp
$(QT5_PLATFORMS_SRCDIR
)/qtlogo.svg
$(QT5_PLATFORMS_SRCDIR
)/qtloader.js
$(dir $(1)) ; \
186 cp
$(call gb_CustomTarget_get_workdir
,static
/emscripten_fs_image
)/soffice.data
$(dir $(1))/soffice.data
; \
187 cp
$(call gb_CustomTarget_get_workdir
,static
/emscripten_fs_image
)/soffice.data.js.metadata
$(dir $(1))/soffice.data.js.metadata \
191 define gb_LinkTarget__command_staticlink
192 $(call gb_Helper_abbreviate_dirs
,\
194 $(if
$(filter EMSCRIPTEN
,$(OS
)),unset PYTHONWARNINGS
;) \
195 $(gb_AR
) $(gb_LTOPLUGINFLAGS
) -rsu
$(1) \
196 $(foreach object
,$(COBJECTS
),$(call gb_CObject_get_target
,$(object
))) \
197 $(foreach object
,$(CXXOBJECTS
),$(call gb_CxxObject_get_target
,$(object
))) \
198 $(foreach object
,$(ASMOBJECTS
),$(call gb_AsmObject_get_target
,$(object
))) \
199 $(foreach object
,$(GENCOBJECTS
),$(call gb_GenCObject_get_target
,$(object
))) \
200 $(foreach object
,$(GENCXXOBJECTS
),$(call gb_GenCxxObject_get_target
,$(object
))) \
201 $(foreach object
,$(GENNASMOBJECTS
),$(call gb_GenNasmObject_get_target
,$(object
))) \
202 $(foreach extraobjectlist
,$(EXTRAOBJECTLISTS
),@
$(extraobjectlist
)) \
203 $(if
$(findstring s
,$(MAKEFLAGS
)),2> /dev
/null
))
206 define gb_LinkTarget__command
207 $(call gb_Output_announce
,$(2),$(true
),LNK
,4)
208 $(call gb_Trace_StartRange
,$(2),LNK
)
209 $(if
$(filter CppunitTest Executable
,$(TARGETTYPE
)),$(call gb_LinkTarget__command_dynamiclink
,$(1),$(2)))
210 $(if
$(filter Library
,$(TARGETTYPE
)),$(if
$(filter TRUE
,$(DISABLE_DYNLOADING
)),$(call gb_LinkTarget__command_staticlink
,$(1)),$(call gb_LinkTarget__command_dynamiclink
,$(1),$(2))))
211 $(if
$(filter StaticLibrary
,$(TARGETTYPE
)),$(call gb_LinkTarget__command_staticlink
,$(1)))
212 $(call gb_Trace_EndRange
,$(2),LNK
)
219 gb_Library_SYSPRE
:= lib
220 gb_Library_UNOVERPRE
:= $(gb_Library_SYSPRE
)uno_
222 ifeq ($(DISABLE_DYNLOADING
),TRUE
)
224 gb_Library_PLAINEXT
:= .a
225 gb_Library_PLAINEXT_FOR_BUILD
:= .so
226 gb_Library_DLLEXT
:= .a
230 gb_Library_TARGETTYPEFLAGS
:= -shared
-Wl
,-z
,noexecstack
231 gb_Library_UDK_MAJORVER
:= 3
232 gb_Library_PLAINEXT
:= .so
233 gb_Library_PLAINEXT_FOR_BUILD
:= .so
234 gb_Library_DLLEXT
:= .so
238 gb_Library_RTEXT
:= gcc3
$(gb_Library_PLAINEXT
)
240 gb_Library_OOOEXT
:= $(gb_Library_DLLPOSTFIX
)$(gb_Library_PLAINEXT
)
241 gb_Library_UNOEXT
:= .uno
$(gb_Library_PLAINEXT
)
243 gb_Library_FILENAMES
:= \
244 $(foreach lib
,$(gb_Library_OOOLIBS
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_OOOEXT
)) \
245 $(foreach lib
,$(gb_Library_PLAINLIBS_NONE
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_PLAINEXT
)) \
246 $(foreach lib
,$(gb_Library_PLAINLIBS_URE
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_PLAINEXT
)) \
247 $(foreach lib
,$(gb_Library_PLAINLIBS_OOO
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_PLAINEXT
)) \
248 $(foreach lib
,$(gb_Library_PLAINLIBS_OXT
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_PLAINEXT
)) \
249 $(foreach lib
,$(gb_Library_PRIVATELIBS_URE
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_OOOEXT
)) \
250 $(foreach lib
,$(gb_Library_EXTENSIONLIBS
),$(lib
):$(lib
)$(gb_Library_UNOEXT
)) \
252 ifeq ($(DISABLE_DYNLOADING
),TRUE
)
254 gb_Library_FILENAMES
+= \
255 $(foreach lib
,$(gb_Library_RTVERLIBS
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_RTEXT
)) \
256 $(foreach lib
,$(gb_Library_UNOVERLIBS
),$(lib
):$(gb_Library_UNOVERPRE
)$(lib
)$(gb_Library_PLAINEXT
)) \
260 gb_Library_FILENAMES
+= \
261 $(foreach lib
,$(gb_Library_RTVERLIBS
),$(lib
):$(gb_Library_SYSPRE
)$(lib
)$(gb_Library_RTEXT
).
$(gb_Library_UDK_MAJORVER
)) \
262 $(foreach lib
,$(gb_Library_UNOVERLIBS
),$(lib
):$(gb_Library_UNOVERPRE
)$(lib
)$(gb_Library_PLAINEXT
).
$(gb_Library_UDK_MAJORVER
)) \
266 gb_Library_LAYER
:= \
267 $(foreach lib
,$(gb_Library_OOOLIBS
),$(lib
):OOO
) \
268 $(foreach lib
,$(gb_Library_PLAINLIBS_URE
),$(lib
):URELIB
) \
269 $(foreach lib
,$(gb_Library_PLAINLIBS_OOO
),$(lib
):OOO
) \
270 $(foreach lib
,$(gb_Library_PLAINLIBS_OXT
),$(lib
):OXT
) \
271 $(foreach lib
,$(gb_Library_PLAINLIBS_NONE
),$(lib
):NONE
) \
272 $(foreach lib
,$(gb_Library_PRIVATELIBS_URE
),$(lib
):URELIB
) \
273 $(foreach lib
,$(gb_Library_RTVERLIBS
),$(lib
):URELIB
) \
274 $(foreach lib
,$(gb_Library_UNOVERLIBS
),$(lib
):URELIB
) \
275 $(foreach lib
,$(gb_Library_EXTENSIONLIBS
),$(lib
):OXT
) \
277 define gb_Library__get_rpath
278 $(if
$(1),$(strip -Wl
,-z
,origin '-Wl,-rpath,$(1)' -Wl
,-rpath-link
,$(INSTDIR
)/program
))
281 define gb_Library_get_rpath
282 $(call gb_Library__get_rpath
,$(call gb_LinkTarget__get_rpath_for_layer
,$(call gb_Library_get_layer
,$(1))))
285 define gb_Library_Library_platform
286 $(call gb_LinkTarget_get_target
,$(2)) : RPATH
:= $(call gb_Library_get_rpath
,$(1))
290 gb_Library__set_soversion_script_platform
= $(gb_Library__set_soversion_script
)
292 gb_Library_get_sdk_link_dir
= $(INSTDIR
)/$(SDKDIRNAME
)/lib
294 gb_Library_get_sdk_link_lib
= $(gb_Library_get_versionlink_target
)
300 gb_Executable_LAYER
:= \
301 $(foreach exe
,$(gb_Executable_UREBIN
),$(exe
):UREBIN
) \
302 $(foreach exe
,$(gb_Executable_SDK
),$(exe
):SDKBIN
) \
303 $(foreach exe
,$(gb_Executable_OOO
),$(exe
):OOO
) \
304 $(foreach exe
,$(gb_Executable_NONE
),$(exe
):NONE
) \
307 define gb_Executable__get_rpath
308 $(strip -Wl
,-z
,origin $(if
$(1),'-Wl$(COMMA)-rpath$(COMMA)$(1)') -Wl
,-rpath-link
,$(INSTDIR
)/program
)
311 define gb_Executable_get_rpath
312 $(call gb_Executable__get_rpath
,$(call gb_LinkTarget__get_rpath_for_layer
,$(call gb_Executable_get_layer
,$(1))))
315 define gb_Executable_Executable_platform
316 $(call gb_LinkTarget_get_target
,$(2)) : RPATH
:= $(call gb_Executable_get_rpath
,$(1))
323 gb_CppunitTest_CPPTESTPRECOMMAND
:= \
324 $(call gb_Helper_extend_ld_path
,$(WORKDIR
)/UnpackedTarball
/cppunit
/src
/cppunit
/.libs
)
325 gb_CppunitTest_get_filename
= libtest_
$(1).so
326 gb_CppunitTest_get_ilibfilename
= $(gb_CppunitTest_get_filename
)
327 gb_CppunitTest_malloc_check
:= -ex
'set environment MALLOC_CHECK_=2; set environment MALLOC_PERTURB_=153'
329 define gb_CppunitTest_CppunitTest_platform
330 $(call gb_LinkTarget_get_target
,$(2)) : RPATH
:= $(call gb_Library__get_rpath
,$(call gb_LinkTarget__get_rpath_for_layer
,NONE
))
334 define gb_CppunitTest_postprocess
335 $(SRCDIR
)/solenv
/bin
/gdb-core-bt.sh
$(1) $(2) $(3)
340 ifneq ($(OOO_TEST_SOFFICE
),)
341 gb_JunitTest_SOFFICEARG
:=$(OOO_TEST_SOFFICE
)
343 ifneq ($(gb_JunitTest_DEBUGRUN
),)
344 gb_JunitTest_SOFFICEARG
:=connect
:pipe
,name
=$(USER
)
346 gb_JunitTest_SOFFICEARG
:=path
:$(INSTROOT
)/$(LIBO_BIN_FOLDER
)/soffice
350 define gb_JunitTest_JunitTest_platform
351 $(call gb_JunitTest_get_target
,$(1)) : DEFS
:= \
352 -Dorg.openoffice.
test.arg.env
=$(gb_Helper_LIBRARY_PATH_VAR
)"$$$${$(gb_Helper_LIBRARY_PATH_VAR)+=$$$$$(gb_Helper_LIBRARY_PATH_VAR)}" \
353 -Dorg.openoffice.
test.arg.user
=$(call gb_Helper_make_url
,$(call gb_JunitTest_get_userdir
,$(1))) \
354 -Dorg.openoffice.
test.arg.workdir
=$(call gb_JunitTest_get_userdir
,$(1)) \
355 -Dorg.openoffice.
test.arg.postprocesscommand
=$(SRCDIR
)/solenv
/bin
/gdb-core-bt.sh \
356 -Dorg.openoffice.
test.arg.soffice
="$(gb_JunitTest_SOFFICEARG)" \
362 gb_PythonTest_PRECOMMAND
:= $(gb_CppunitTest_CPPTESTPRECOMMAND
)
366 define gb_Module_DEBUGRUNCOMMAND
367 OFFICESCRIPT
=`mktemp` && \
368 printf
'if [ -e $(INSTROOT)/program/ooenv ]; then . $(INSTROOT)/program/ooenv; fi\n' > $${OFFICESCRIPT} && \
369 printf
"PYTHONWARNINGS=default gdb $(INSTROOT)/$(LIBO_BIN_FOLDER)/soffice.bin" >> $${OFFICESCRIPT} && \
370 printf
" -ex \"set args --norestore --nologo '--accept=pipe,name=$(USER);urp;' %s\"" \
371 "$(subst ","\\\"",$(value gb_DBGARGS
))" >> $${OFFICESCRIPT} && \
372 $(SHELL) $${OFFICESCRIPT} && \
376 # InstallModuleTarget class
378 define gb_InstallModuleTarget_InstallModuleTarget_platform
379 $(call gb_InstallModuleTarget_add_defs,$(1),\
388 # InstallScript class
390 gb_InstallScript_EXT := .ins
392 # CliAssemblyTarget class
394 gb_CliAssemblyTarget_POLICYEXT :=
395 gb_CliAssemblyTarget_get_dll :=
399 gb_Extension_LICENSEFILE_DEFAULT := $(INSTROOT)/LICENSE
401 # UnpackedTarget class
403 gb_UnpackedTarget_TARFILE_LOCATION := $(TARFILE_LOCATION)
405 # UnoApiHeadersTarget class
407 ifeq ($(DISABLE_DYNLOADING),TRUE)
408 gb_UnoApiHeadersTarget_select_variant = $(if $(filter udkapi,$(1)),comprehensive,$(2))
410 gb_UnoApiHeadersTarget_select_variant = $(2)
413 # UIMenubarTarget class
415 define gb_UIMenubarTarget__command
416 $(call gb_Output_announce,$(2),$(true),UIM,1)
417 $(call gb_Trace_StartRange,$(2),UIM)
419 $(call gb_Trace_EndRange,$(2),UIM)
423 gb_UIMenubarTarget_UIMenubarTarget_platform :=
426 gb_Python_PRECOMMAND := PYTHONHOME="$(INSTDIR
)/program
/python-core-
$(PYTHON_VERSION
)" PYTHONPATH="$${PYPATH
:+$$PYPATH:}$(INSTDIR
)/program
/python-core-
$(PYTHON_VERSION
)/lib
:$(INSTDIR
)/program
/python-core-
$(PYTHON_VERSION
)/lib
/lib-dynload
"
427 gb_Python_INSTALLED_EXECUTABLE := /bin/sh $(INSTROOT)/program/python
428 # this is passed to gdb as executable when running tests
429 gb_Python_INSTALLED_EXECUTABLE_GDB := $(INSTROOT)/program/python.bin
431 include $(GBUILDDIR)/platform/com_GCC_class.mk
433 # vim: set noet sw=4: