forked from tsduck/tsduck
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile.common
960 lines (905 loc) · 35 KB
/
Makefile.common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
#-----------------------------------------------------------------------------
#
# Copyright (c) 2005-2017, Thierry Lelegard
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
#
#-----------------------------------------------------------------------------
#
# Common GNU Make definitions.
#
# This file is completely generic for all kinds of projects. It should be
# located in the root directory of the project and included by all makefiles
# in the directory tree.
#
# The inclusion must be expressed in relative path format.
# Example: include ../../Makefile.common
#
# A few input variables may be defined by each makefile before including
# the one. See the section "Input variables" below. After inclusion, several
# useful variables are defined. See the section "Output variables" below.
#
# By default, if the parent makefile does not define a first target before
# including this file, the default make target is "default" and should be
# defined in the parent makefile.
#
# This common makefile also defines a few common targets which are usable
# everywhere. See the section "Common targets" below.
#
#-----------------------------------------------------------------------------
#
# Common targets
# --------------
# The following make targets are defined by this makefile and are
# consequently available in all directories.
#
# clean:
# Delete all standard intermediate or temporary files (object files, core
# files, etc.) for the current architecture. The production files
# (executables, shared libraries, etc.) and files for other architectures
# are not deleted. Recursively apply to all subdirectories.
#
# cmacros:
# Display the predefined macros for the C compiler.
#
# coverity:
# Run coverity, a C/C++ static code analyzer, on the source tree starting
# at the current directory. Here, we only support the "Coverity Scan
# Self-Build" free online service for open-source projects.
#
# cppcheck:
# Run cppcheck, a C/C++ static code analyzer, on the source tree starting
# at the current directory.
#
# cppcheck-xml:
# Same as cppcheck, but output in XML format.
#
# cxxmacros:
# Display the predefined macros for the C++ compiler.
#
# debug:
# Build the default target of the current directory with the debug options.
#
# distclean:
# Distant clean, revert to the initial source environment, remove built
# files. See also the description of the input variable EXTRA_DISTCLEAN
# below. Recursively apply to all subdirectories.
#
# doxygen:
# Run doxygen, the source code documentation generator. If no Doxyfile
# if found in the current directory, recurse in subdirectories.
#
# flawfinder:
# Run flawfinder, a C/C++ static code analyzer, on the source tree starting
# at the current directory.
#
# listvars:
# Display make variables for debug purposes.
#
# m32:
# Build the default target of the current directory for 32-bit target
# (see input variable M32).
#
# optsize:
# Alternate target to recompile with optimizations for reduced code size.
#
# scan-build:
# Run scan-build, the clang C/C++ static code analyzer, on the source tree
# starting at the current directory.
#
# unixify:
# Recursively cleanup Windows oddities in C/C++source files, including
# subdirectories. By default, Visual C++ indents with tabs and tabs are 4
# characters wide.
#
#-----------------------------------------------------------------------------
#
# Input variables
# ---------------
# The following variables may be set in the parent makefile before inclusion.
#
# ARFLAGS_EXTRA
# Additional options for the "ar" command.
# This variable can be defined after inclusion of this makefile.
#
# CFLAGS_EXTRA
# Additional options for the C compiler.
# This variable can be defined after inclusion of this makefile.
#
# CFLAGS_INCLUDES
# Contains specific include options for both C and C++ (typically -I...)
#
# CFLAGS_OPTIMIZE
# Contains specific optimization for the gcc compiler. Defaults to -O2.
# Ignored if DEBUG is defined.
#
# CFLAGS_STANDARD
# C language standard level. Default to -std=c11.
# This variable can be defined after inclusion of this makefile.
#
# COVERITY
# Contains the absolute path of the Coverity static code analyzer.
# If empty, cov-build (Coverity analyzer) is searched in $PATH.
#
# COVERITY_DIR
# Directory where cov-build creates the report. The default is the
# recommended name for the scan.coverity online service: cov-int
#
# COVERITY_SOURCES
# Root directory on which to run coverity.
# By default, use the source tree starting at current directory.
#
# CPPCHECK
# Contains the absolute path of the cppcheck static code analyzer.
# If empty, cppcheck is searched in $PATH.
#
# CPPCHECK_FLAGS
# Contains additional options for cppcheck. Typically empty since the
# usual options are automatically added in this makefile.
#
# CPPCHECK_SOURCES
# List of source files or directories on which to run cppcheck.
# By default, use the source tree starting at current directory.
#
# CVPATH
# Contains directories where *.h and *.c files are searched. "vpath"
# directives are defined accordingly.
#
# CXXFLAGS_EXTRA
# Additional options for the C++ compiler.
# This variable can be defined after inclusion of this makefile.
#
# CXXFLAGS_INCLUDES
# Contains additional specific include options for C++ only.
#
# CXXFLAGS_STANDARD
# C++ language standard level. Default to -std=c++11.
# This variable can be defined after inclusion of this makefile.
#
# CXXVPATH
# Contains directories where *.h and *.cpp files are searched. "vpath"
# directives are defined accordingly.
#
# DEBUG
# If defined (any non-empty value), the debug information is included in
# any compilation. Optimizations are turned off.
#
# DONT_BUILD_DEPS
# Do not attempt to build the header dependency files. Useful when the
# source file depend on dynamically generated header files (initially
# non-existent).
#
# DOXYGEN
# Contains the absolute path of the doxygen documentation generator.
# If empty, doxygen is searched in $PATH.
#
# DOXYGEN_FLAGS
# Contains the options for doxygen. Typically empty.
#
# EXTRA_CLEAN
# List the additional files that should be deleted by "make clean".
# This variable can be defined after inclusion of this makefile.
#
# EXTRA_DISTCLEAN
# List the additional files that should be deleted by "make distclean".
# This variable can be defined after inclusion of this makefile.
#
# FLAWFINDER
# Contains the absolute path of the flawfinder static code analyzer.
# If empty, flawfinder is searched in $PATH.
#
# FLAWFINDER_FLAGS
# Contains additional options for flawfinder. Typically empty since the
# usual options are automatically added in this makefile.
#
# FLAWFINDER_SOURCES
# List of source files or directories on which to run flawfinder.
# By default, use the source tree starting at current directory.
#
# GCOV
# If defined (any non-empty value), compile and link with gcov support.
# The preprocessing macro GCOV is also defined for C/C++ compilations.
#
# LDCXX
# Must be defined to a non-empty value to include the C++ libraries in
# the link commands. Automatically defined if any C++ source file (*.cpp)
# is present. Define it explicitly if you need the C++ libraries without
# C++ source files in the make working directory.
#
# LDFLAGS_EXTRA
# Additional options for the linker.
# This variable can be defined after inclusion of this makefile.
#
# M32
# If defined (any non-empty value), compile for 32-bit target when running
# in 64-bit host. More precisely, on a x86-84 host platform, generate code
# for i686 target (cross-compilation). Requirement:
# - Ubuntu: apt-get install gcc-multilib g++-multilib
# - Fedora: dnf install glibc-devel.i686 libstdc++-devel.i686
#
# MAKEINFO
# Contains the absolute path of the makeinfo utility (part of Texinfo).
# If empty, makeinfo is searched in $PATH.
#
# NODEPS
# List of make targets in the parent makefile which shall not enforce
# the generation of header dependency files. This is a bit complicated
# and, most of the time, there is no need to set this variable.
#
# When make is invoked, the .dep files which list for each C/C++ source
# file the .h header dependencies are automatically updated. This is
# required for most targets, those which build files. Some targets are
# informational or do not need to build object files. In this case,
# rebuilding the .dep files is useless but harmless. However, in some
# cases such as the standard "clean" targets, the .dep files should
# not be rebuilt. In fact, they are deleted by the target. In these
# cases, the "clean" targets must not implicitly rebuild the .dep
# files. The standard "clean" targets are automatically added in NODEPS,
# there is no need to set them. However, if a makefile defines some
# non-standard "clean" targets, it should set them in NODEPS before
# inclusion of this make file.
#
# RECURSE_ORDER
# Define which subdirectories should be used in which order in the
# $(RECURSE) shell command. Non-existent subdirectories are ignored.
# See RECURSE in the section "Output variables" below.
#
# Caveat: If you do not want to recurse into subdirectories, do not
# define the variable as empty. If it is empty, the default will apply
# (all subdirectories). Instead, define its value as something that does
# not correspond to any existing directory (eg. RECURSE_ORDER = none).
#
# RPMBUILDFLAGS_EXTRA
# Additional options for the "rpmbuild" command.
# This variable can be defined after inclusion of this makefile.
#
# SCANBUILD
# Contains the absolute path of the scan-build static code analyzer.
# If empty, scan-build is searched in $PATH.
#
# SCANBUILD_FLAGS
# Contains additional options for scan-build. Typically empty since the
# usual options are automatically added in this makefile.
#
# SCANBUILD_SOURCES
# List of source files or directories on which to run scan-build.
# By default, use the source tree starting at current directory.
#
# SOFLAGS
# Specific options when creating shared objects (.so files).
# This variable can be defined after inclusion of this makefile.
#
# SYSPREFIX
# Optional installation prefix. If not defined, will be set on output.
# See SYSPREFIX in "Output variables".
#
# TARGET_ARCH
# Contains the target architecture for gcc. Defaults to -march=`uname -m`.
# Should be overriden if your `uname -m` is not recognized by gcc.
#
# TEXI2DVI
# Contains the absolute path of the texi2dvi utility (part of Texinfo).
# If empty, texi2dvi is searched in $PATH.
#
#-----------------------------------------------------------------------------
#
# Output variables
# ----------------
# The following variables are defined in this included makefile and are
# available in the parent makefile after inclusion.
#
# ARFLAGS
# Options which are applied to the archiver (ar) when adding a module into
# a static library.
#
# CFLAGS
# Options which are applied to C compilations.
#
# CFLAGS_INCLUDES
# Same as input variables with additional common include libraries.
#
# CFLAGS_FULLSPEED
# Contains the C/C++ optimization options for maximum execution speed, at
# the expense of code size. Can be used in the parent makefile to specify
# that some selected modules should be compiled for full speed. Example:
#
# $(OBJDIR)/fast1.o $(OBJDIR)/fast2.o: CFLAGS_OPTIMIZE = $(CFLAGS_FULLSPEED)
#
# CFLAGS_OPTSIZE
# Contains the C/C++ optimization options for minimum code size.
# Same usage as CFLAGS_FULLSPEED.
#
# COMMA
# Contains a comma. Use $(COMMA) wherever a plain "," is syntaxtically not
# allowed such as in functions.
#
# CONTINUE
# Contains a non-empty value if "make -k" is specified (ie. continue on
# error). Otherwise, it is empty.
#
# CORE_COUNT
# Contains the number of physical CPU cores in the machine.
#
# CPPCHECK_FLAGS
# Same as input variables with additional usual options. In debug mode
# (when DEBUG is defined) the diagnostics are more aggressive but may
# generate false positives.
#
# CPU_COUNT
# Contains the number of logical CPU's in the machine. With hyperthreaded
# CPU cores, CPU_COUNT is typically twice CORE_COUNT.
#
# CXXFLAGS
# Options which are applied to C++ compilations.
#
# CYGWIN
# Defined to a non-empty value in a Cygwin environment.
#
# ETCDIR
# Name of the system configuration directory. This is /etc if $(SYSPREFIX)
# is /usr and $(SYSPREFIX)/etc otherwise.
#
# EXE_SUFFIX
# Executable files suffix, ".exe" on Windows, nothing otherwise.
#
# EXECS
# All executable files to build, based on the list of main programs from
# $(MODULES_MAIN).
#
# F_COMMAND (function)
# This function searches a command with F_SEARCH. If the command is not
# found, return the second parameter as default value. The following
# example searches for a command named "gsed" and, if not found, use
# command "sed" as fallback: $(call F_COMMAND,gsed,sed)
#
# F_SEARCH (function)
# This function searches a command in $PATH and in a few other predefined
# directories. Return the full path of the first found, empty if not found.
# Example: $(call F_SEARCH,ls)
#
# FGREP
# Name of "fgrep" command. If some "gfgrep" is found, use it instead.
#
# FLAWFINDER_FLAGS
# Same as input variables with additional usual options.
#
# GCC_VERSION
# Contain the current GCC version, usually in form x.y.z
#
# GREP
# Name of "grep" command. If some "ggrep" is found, use it instead.
#
# HEADERS
# List of all header names, that is to say the list of all "f" for which
# a source file f.h exists.
#
# LDFLAGS
# Options which are applied to the linker.
#
# LD_LIBRARY_PATH_NAME
# Name of the environment variable containing the search path for the
# shareable libraries. Typically LD_LIBRARY_PATH on native unices and
# PATH on Windows-based environments such as Cygwin.
#
# LLVM_VERSION
# Contain the current LLVM compiler version, usually in form x.y.z.
# Empty if LLVM is not available.
#
# LOCAL_ARCH
# Local processor exact architecture ("i686", "x86_64", "armv7l", etc.)
#
# LOCAL_OS
# Local operating system name in lower-case ("linux", "cygwin", etc.)
#
# MACOS
# Defined to a non-empty value on MacOS systems.
#
# MAIN_ARCH
# Local processor architecture family ("i386", "x86_64", "arm", etc.)
#
# MODULES
# List of all modules names, that is to say the list of all "f" for which
# a source file f.c or f.cpp exists.
#
# MODULES_LIB
# List of all modules names which are not main programs, that is to say the
# list of all "f" for which a source file f.c or f.cpp exists and a source
# file f.h exists.
#
# MODULES_MAIN
# List of all modules names which are main programs, that is to say the list
# of all "f" for which a source file f.c or f.cpp exists but no file f.h
# exists.
#
# NORECURSE_SUBDIRS
# List of subdirectories patterns to ignore in make recursion. The parent
# makefile may append local subdirectories to this variable.
#
# NOSOURCE
# List of file patterns which are typically not source files. This can
# be used to filter file names when creating a backup or an archive of
# the source files.
#
# OBJDIR
# Name of the subdirectory which receives all generated binary files.
# Typically either "release-{arch}" or "debug-{arch}".
#
# OBJS
# All object files (.o) to build, for all C/C++ source files.
#
# OBJS_LIB
# All object files (.o) to build which are not main programs, ie. for all
# $(MODULES_LIB). These object files will typically go into a library.
#
# OBJS_MAIN
# All object files (.o) to build which are main programs, ie. for all
# $(MODULES_MAIN).
#
# RECURSE
# A shell command which applies the current make target to all or some
# subdirectories of the current directory. Can be used in make targets
# to recursively apply this target. By default, the $(RECURSE) command
# apply to all subdirectories in alphabetical order. If the input variable
# RECURSE_ORDER is defined and non empty, it is used as the list of
# subdirectories to recurse into.
#
# RECURSE_SUBDIRS
# Actual recurse order. If the user did not define RECURSE_ORDER, use all
# subdirectories, except those for which we know there is nothing to make.
#
# RPMBUILD
# Name of rpmbuild command.
#
# RPMBUILDFLAGS
# Flags for rpmbuild command. If M32 is defined, the rpmbuild options
# build a 32-bit package.
#
# ROOTDIR
# Absolute path of the directory where this Makefile.common file is
# located. By convention, this is the root directory of the project.
#
# SCANBUILD_FLAGS
# Same as input variables with additional usual options.
#
# SED
# Name of "sed" command. If some "gsed" is found, use it instead.
#
# SOURCES
# All C and C++ source files in the current directory.
#
# SPACE
# Contains a space character. Use $(SPACE) to force a space wherever a " "
# is ignored such as in functions and expressions.
#
# SUBDIRS
# List of all subdirectories of the current directory in alphabetical order.
#
# SYSPREFIX
# Installation prefix. If not set on input, defined as /usr/local on macOS
# and /usr on other Unix (including Linux).
#
# TEXI2HTML_FLAGS
# Makeinfo flags used in .texi to .html transformation.
#
# TEXI2INFO_FLAGS
# Makeinfo flags used in .texi to .info transformation.
#
# TEXI2PDF_FLAGS
# Texi2dvi flags used in .texi to .pdf transformation.
#
# USRLIBDIR
# Name of the library directory for the target architecture. This is
# $(SYSPREFIX)/lib64 for Linux x86_64 and $(SYSPREFIX)/lib elsewhere.
#
#-----------------------------------------------------------------------------
# If no target precedes the inclusion of this file, use "default" as target.
.PHONY: first default
first: default
@true
# General note: To speed up make recursion, some variables are exported when
# their definition take some time.
# Some nerds define exotic shells as default. Stay to a known shell.
# Skip initialization files to speed up and reproduceability.
SHELL := /bin/bash --noprofile --norc
# Enforce English locale by default.
LANG=en_US
# Define functions to search commands (see comments in header)
F_SEARCH = $(firstword $(wildcard $(addsuffix /$(1),$(subst :, ,$(PATH)) /usr/bin /usr/sbin /usr/local/bin $(HOME)/bin)))
F_COMMAND = $(if $(call F_SEARCH,$(1)),$(call F_SEARCH,$(1)),$(2))
export F_SEARCH F_COMMAND
# Find faster alternatives to sed and grep.
SED ?= $(call F_COMMAND,gsed,sed)
GREP ?= $(call F_COMMAND,ggrep,grep)
FGREP ?= $(call F_COMMAND,gfgrep,fgrep)
export SED GREP FGREP
# Representation of a space and a comma character
EMPTY =
SPACE = $(EMPTY) $(EMPTY)
COMMA = ,
# Recursive invocations of make should be silent.
MAKEFLAGS += --no-print-directory
# Check if "make -k" is specified (ie. continue on error).
ifneq ($(findstring k,$(filter-out --%,$(MAKEFLAGS))),)
CONTINUE := true
else
CONTINUE :=
endif
# The directory which contains the currently included Makefile is the project root.
ROOTDIR := $(abspath $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))))
# List of subdirectories in the current directory.
SUBDIRS = $(sort $(patsubst %/,%,$(wildcard */)))
# List of subdirectories to ignore in make recursion.
NORECURSE_SUBDIRS += debug release debug-% release-% Debug Release Debug-% Release-% .vs ipch %.t2d .git cov-int
# Actual recurse order. If the user did not define RECURSE_ORDER, use all
# subdirectories, except those for which we know there is nothing to make.
RECURSE_SUBDIRS = $(filter $(SUBDIRS),$(filter-out $(NORECURSE_SUBDIRS),$(if $(RECURSE_ORDER),$(RECURSE_ORDER),$(SUBDIRS))))
# $(RECURSE) is a shell command which recurses the current
# make targets in the subdirectories (useful for "all" or "clean").
RECURSE = for dir in $(RECURSE_SUBDIRS); do $(MAKE) -C $$dir $@ $(if $(CONTINUE),,|| break); done
# Operating system, architecture.
ifndef LOCAL_OS
export LOCAL_OS := $(shell uname -s | tr A-Z a-z)
export LOCAL_ARCH := $(shell uname -m)
endif
ifeq ($(LOCAL_OS),darwin)
MACOS = true
endif
# Logical CPU and physical core count.
ifndef CPU_COUNT
ifdef MACOS
export CPU_COUNT := $(shell sysctl -n hw.logicalcpu 2>/dev/null)
export CPU_COUNT := $(if $(CPU_COUNT),$(CPU_COUNT),1)
export CORE_COUNT := $(shell sysctl -n hw.physicalcpu 2>/dev/null)
export CORE_COUNT := $(if $(CORE_COUNT),$(CORE_COUNT),$(CPU_COUNT))
else
export CPU_COUNT := $(shell nproc 2>/dev/null)
export CPU_COUNT := $(if $(CPU_COUNT),$(CPU_COUNT),1)
export CORE_COUNT := $(shell $(FGREP) -m1 'cpu cores' /proc/cpuinfo 2>/dev/null | cut -d ' ' -f3)
export CORE_COUNT := $(if $(CORE_COUNT),$(CORE_COUNT),$(CPU_COUNT))
endif
endif
# Get current compiler version, usually in form x.y.z
ifndef GCC_VERSION_DONE
export GCC_VERSION_DONE = true
export GCC_VERSION := $(word 3,$(shell gcc -v 2>&1 | $(GREP) '^gcc version'))
export GCC_MAJOR := $(firstword $(subst .,$(SPACE),$(GCC_VERSION)))
ifeq ($(shell test 0$(GCC_MAJOR) -ge 6; echo $$?),0)
export GCC_6_OR_MORE := true
endif
export LLVM_VERSION := $(shell clang --version 2>&1 | $(GREP) -i "llvm version" | $(SED) -e 's/.*version *//' -e 's/ .*//')
endif
# When C++ source files are present, automatically define LDCXX.
ifndef LDCXX
ifneq ($(wildcard *.cpp),)
export LDCXX = true
endif
endif
# Detect Cygwin platform. Impacts:
# - The executables are started by the Windows loader which uses distinct environment
# variables for shared library resolution.
# - The option -fPIC generates a stupid error:
# "-fPIC ignored for target (all code is position independent)"
ifneq ($(subst cygwin,,$(LOCAL_OS)),$(LOCAL_OS))
CYGWIN = true
LOCAL_OS := cygwin
LD_LIBRARY_PATH_NAME := PATH
CFLAGS_FPIC :=
else
LD_LIBRARY_PATH_NAME := LD_LIBRARY_PATH
CFLAGS_FPIC := -fPIC
endif
# Executable files suffix
ifdef CYGWIN
EXE_SUFFIX := .exe
else
EXE_SUFFIX :=
endif
# Define compilation flags for 32-bit cross-compilation.
# Target architecture is skipped on ARM because of numerous variants.
ifdef M32
override MAIN_ARCH := i386
override TARGET_ARCH := -march=i686
CFLAGS_M32 := -m32
LDFLAGS_M32 := -m32
else ifndef MAIN_ARCH
MAIN_ARCH := $(shell uname -m | $(SED) -e 's/i.86/i386/' -e 's/arm.*/arm/')
TARGET_ARCH := $(if $(subst arm,,$(MAIN_ARCH)),-march=$(LOCAL_ARCH:x86_64=x86-64),)
CFLAGS_M32 :=
LDFLAGS_M32 :=
endif
export MAIN_ARCH TARGET_ARCH
# Alternate target to recompile with debug options
.PHONY: debug
debug:
+@$(MAKE) DEBUG=true
# Alternate target to recompile for 32-bit target
.PHONY: m32
m32:
+@$(MAKE) M32=true
# Compilation flags for various types of optimization.
CFLAGS_OPTIMIZE ?= -O2 -fno-strict-aliasing
CFLAGS_FULLSPEED = -O3 -fno-strict-aliasing -funroll-loops -fomit-frame-pointer
CFLAGS_OPTSIZE = -Os -fno-strict-aliasing
# Alternate target to recompile with optimizations for reduced code size.
.PHONY: optsize
optsize:
+@$(MAKE) CFLAGS_OPTIMIZE="$(CFLAGS_OPTSIZE)"
# On MacOS, HomeBrew development packages are installed in /usr/local.
ifdef MACOS
CFLAGS_INCLUDES += -I/usr/local/include
LDLIBS := -L/usr/local/lib $(LDLIBS)
endif
# Include paths for C++ also use include paths for C.
CXXFLAGS_INCLUDES += $(CFLAGS_INCLUDES)
# Always use maximal or even paranoid warning mode.
COMMON_WARNINGS = -Werror -Wall -Wextra -Wformat-nonliteral -Wformat-security -Wswitch-default \
-Wuninitialized -Wno-unused-parameter -Wfloat-equal -Wundef -Wpointer-arith
CFLAGS_WARNINGS = $(COMMON_WARNINGS) -Wstrict-prototypes -Wmissing-prototypes -Winit-self -Wtraditional \
-Wbad-function-cast -Wc++-compat
CXXFLAGS_WARNINGS = $(COMMON_WARNINGS) -Woverloaded-virtual -Wctor-dtor-privacy -Wnon-virtual-dtor \
-Woverloaded-virtual -Wsign-promo
ifneq (,$(or $(MACOS),$(subst 4,,$(lastword $(sort 4 $(GCC_MAJOR))))))
# Use these warnings on MacOS or with GCC 5.x and higher only.
# They are supported with GCC 4.x but are totally insane before 5.x.
COMMON_WARNINGS += -Wshadow -Wpedantic
CXXFLAGS_WARNINGS += -Weffc++
endif
ifdef MACOS
CFLAGS_WARNINGS += -Wno-unused-command-line-argument
CXXFLAGS_WARNINGS += -Wno-unused-command-line-argument
else
CFLAGS_WARNINGS += -Wcast-align
CXXFLAGS_WARNINGS += -Wcast-align -Wstrict-null-sentinel
ifdef GCC_6_OR_MORE
CXXFLAGS_WARNINGS += -Wsuggest-override
endif
endif
# Language levels.
CFLAGS_STANDARD ?= -std=c11
CXXFLAGS_STANDARD ?= -std=c++11
# Compilation flags for security.
COMMON_SECURITY = -fstack-protector-all
CFLAGS_SECURITY = $(COMMON_SECURITY)
CXXFLAGS_SECURITY = $(COMMON_SECURITY)
# Compilation flags in debug mode.
ifdef DEBUG
CFLAGS_DEBUG = -g -DDEBUG=1
LDFLAGS_DEBUG =
else
CFLAGS_DEBUG = $(CFLAGS_OPTIMIZE)
LDFLAGS_DEBUG =
endif
# Compilation flags for code coverage using gcov.
ifdef GCOV
CFLAGS_GCOV = --coverage -DGCOV=1
LDFLAGS_GCOV = --coverage
else
CFLAGS_GCOV =
LDFLAGS_GCOV =
endif
# External libraries
LDLIBS += $(if $(LDCXX),-lstdc++,) -lpthread $(if $(MACOS),,-lrt) -lm
# Global compilation flags.
# Additional flags can be passed on the "make" command line using FLAGS_EXTRA.
CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_M32) $(CFLAGS_GCOV) $(CFLAGS_WARNINGS) $(CFLAGS_SECURITY) $(CFLAGS_INCLUDES) \
$(TARGET_ARCH) $(CFLAGS_FPIC) $(CFLAGS_STANDARD) $(CFLAGS_EXTRA)
CXXFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_M32) $(CFLAGS_GCOV) $(CXXFLAGS_WARNINGS) $(CXXFLAGS_SECURITY) $(CXXFLAGS_INCLUDES) \
$(TARGET_ARCH) $(CFLAGS_FPIC) $(CXXFLAGS_STANDARD) $(CXXFLAGS_EXTRA)
LDFLAGS = $(LDFLAGS_DEBUG) $(LDFLAGS_M32) $(LDFLAGS_GCOV) $(TARGET_ARCH) $(LDFLAGS_EXTRA)
ARFLAGS = rc$(if $(MACOS),,U) $(ARFLAGS_EXTRA)
# Output subdirectories in each project directory
ifdef DEBUG
OBJDIR = debug-$(MAIN_ARCH)
else
OBJDIR = release-$(MAIN_ARCH)
endif
# Implicit search directives.
ifneq ($(CVPATH),)
vpath %.c $(CVPATH)
endif
ifneq ($(CXXVPATH),)
vpath %.cpp $(CXXVPATH)
endif
ifneq ($(CVPATH)$(CXXVPATH),)
vpath %.h $(CVPATH) $(CXXVPATH)
endif
# On macOS, /usr/local is used without system privileges.
# On x86_64, the libraries are installed in lib64, not lib.
SYSPREFIX ?= $(if $(MACOS),/usr/local,/usr)
ETCDIR ?= $(if $(subst /usr,,$(SYSPREFIX)),$(SYSPREFIX)/etc,/etc)
USRLIBDIR ?= $(if $(subst linux-x86_64,,$(LOCAL_OS)-$(MAIN_ARCH)),$(SYSPREFIX)/lib,$(SYSPREFIX)/lib64)
# RPM building.
RPMBUILD ?= rpmbuild
RPMBUILDFLAGS = -ba --clean $(if $(M32),--target $(MAIN_ARCH) -D 'mflags M32=true',) $(RPMBUILDFLAGS_EXTRA)
# Source and object files in current directory.
SOURCES := $(sort $(notdir $(wildcard *.c *.cpp $(addsuffix /*.c,$(CVPATH)) $(addsuffix /*.cpp,$(CXXVPATH)))))
HEADERS := $(sort $(notdir $(basename $(wildcard *.h $(addsuffix /*.h,$(CVPATH) $(CXXVPATH))))))
MODULES := $(basename $(SOURCES))
OBJS := $(addprefix $(OBJDIR)/,$(addsuffix .o,$(MODULES)))
MODULES_MAIN := $(sort $(filter-out $(HEADERS),$(MODULES)))
MODULES_LIB := $(sort $(filter-out $(MODULES_MAIN),$(MODULES)))
OBJS_MAIN := $(addprefix $(OBJDIR)/,$(addsuffix .o,$(MODULES_MAIN)))
OBJS_LIB := $(addprefix $(OBJDIR)/,$(addsuffix .o,$(MODULES_LIB)))
EXECS := $(addprefix $(OBJDIR)/,$(MODULES_MAIN))
# Keep intermediate files, avoid using "ar" again.
.SECONDARY:
# When using parallel make ("-j") on Linux, the command "ar" is badly handled.
# This foolish make can run simultaneous "ar" commands on the same .a file,
# which usually results in a corrupted library file. We have to explicitly
# serialize access to the library file using flock. However, flock is specific
# to Linux and not present on MacOS.
FLOCK ?= $(call F_SEARCH,flock)
ARLOCK = $(if $(FLOCK),$(FLOCK) -w 60 $(patsubst %/,%,$(dir $@)),)
export FLOCK
# Compilation rules
$(OBJDIR)/%.o: %.c
@echo ' [CC] $<'; \
mkdir -p $(OBJDIR); \
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
$(OBJDIR)/%.o: %.cpp
@echo ' [CXX] $<'; \
mkdir -p $(OBJDIR); \
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
(%): %
@echo ' [AR] $<'; \
$(ARLOCK) $(AR) $(ARFLAGS) $@ $<
$(OBJDIR)/%: $(OBJDIR)/%.o
@echo ' [LD] $@'; \
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(OBJDIR)/%.so: $(OBJDIR)/%.o
@echo ' [CC] $@'; \
$(CC) $(CFLAGS) $(SOFLAGS) $(LDFLAGS) $^ $(LDLIBS) -shared -o $@
# Object files dependencies (.dep files, included by makefiles)
$(OBJDIR)/%.dep: %.c
@echo ' [DEP] $<'; \
mkdir -p $(OBJDIR); \
$(CC) -MM $(CPPFLAGS) $(CFLAGS_INCLUDES) $(CFLAGS_STANDARD) $(CFLAGS_NO_WARNINGS) $< >$@ && \
$(SED) -i 's,\($*\)\.o[ :]*,$(OBJDIR)/\1.o $@ : ,g' $@ || \
rm -f $@
$(OBJDIR)/%.dep: %.cpp
@echo ' [DEP] $<'; \
mkdir -p $(OBJDIR); \
$(CC) -MM $(CPPFLAGS) $(CXXFLAGS_INCLUDES) $(CXXFLAGS_STANDARD) $(CXXFLAGS_NO_WARNINGS) $< >$@ && \
$(SED) -i 's,\($*\)\.o[ :]*,$(OBJDIR)/\1.o $@ : ,g' $@ || \
rm -f $@
# Rebuild and include all .dep files, unless the explicit targets do not require the .dep files.
NODEPS += clean cmacros coverity cppcheck cppcheck-xml cxxmacros debug m32 distclean doxygen flawfinder listvars scan-build unixify
ifeq ($(DONT_BUILD_DEPS),)
ifneq ($(MAKECMDGOALS),)
DONT_BUILD_DEPS := $(if $(filter-out $(NODEPS),$(MAKECMDGOALS)),,true)
endif
endif
ifeq ($(DONT_BUILD_DEPS),)
-include $(addprefix $(OBJDIR)/,$(addsuffix .dep,$(notdir $(basename $(wildcard *.c *.cpp $(addsuffix /*.c,$(CVPATH)) $(addsuffix /*.cpp,$(CXXVPATH)))))))
endif
# Cleanup utilities
.PHONY: clean distclean
clean:
@echo ' [CLEAN] $(CURDIR)'; \
rm -rf $(EXTRA_CLEAN) *~ \
*.o *.ko *.a *.gcov *.dep *.tmp *.out *.log *.tlog core core.* vgcore.* *.stackdump \
$(OBJDIR)/*.o $(OBJDIR)/*.ko $(OBJDIR)/*.a $(OBJDIR)/*.dep $(OBJDIR)/*.tmp $(OBJDIR)/*.out \
$(OBJDIR)/*.log $(OBJDIR)/*.tlog $(OBJDIR)/core $(OBJDIR)/core.* $(OBJDIR)/vgcore.*
+@$(RECURSE)
distclean: clean
@echo ' [DISTCLEAN] $(CURDIR)'; \
rm -rf $(EXTRA_DISTCLEAN) [Dd]ebug* [Rr]elease* ipch *.exe *.so .kdbgrc.* *.t2d \
.vs *.ncb *.suo *.idb *.sdf *.opensdf *.vcproj.*.user \
*.vcxproj.user *.dll.embed.manifest.dll *.dll.embed.manifest.ilk \
*.VC.db *.VC.opendb cov-int cov-int.* \
*.pro.user *.pro.user.* .tmp_versions
+@$(RECURSE)
# List of file and directory patterns for non-source files.
NOSOURCE = \
.git .svn *.zip *.gz *.tgz [Dd]ebug* [Rr]elease* doxy doxygen *.t2d \
*.o *.so *.ko *.a *.lib *.obj *.exe *.dll *.gcov *.dep .kdbgrc.* \
tmp *.tmp *.out *.log *.tlog core core.* vgcore.* *.stackdump \
.vs ipch *.ncb *.suo *.idb *.sdf *.opensdf *.vcproj.*.user *.user.* \
*.vcxproj.user *.dll.embed.manifest.dll *.dll.embed.manifest.ilk \
.tmp_versions *.VC.db *.VC.dbopen *.VC.opendb *.deb *.rpm *.bz2 *.7z \
*~ *.bak *.autosave cov-int
# Source code documentation generation.
DOXYGEN ?= $(call F_COMMAND,doxygen,doxygen)
.PHONY: doxygen
doxygen:
@[ -e Doxyfile ] && $(DOXYGEN) || $(RECURSE)
# Texinfo document generation.
MAKEINFO ?= makeinfo
TEXI2DVI ?= texi2dvi
ifndef TEXI_MAJOR_VERSION
export TEXI_MAJOR_VERSION := $(shell $(MAKEINFO) --version 2>/dev/null | head -1 | $(SED) -e 's/.* *//' -e 's/\..*//')
export TEXI_MAJOR_VERSION := $(if $(TEXI_MAJOR_VERSION),$(TEXI_MAJOR_VERSION),0)
export TEXI_V5 := $(shell test "$(TEXI_MAJOR_VERSION)" -ge 5 2>/dev/null && echo true)
endif
TEXI2PDF_FLAGS = --batch --quiet --tidy
TEXI2HTML_FLAGS = --no-split $(if $(TEXI_V5),--set-customization-variable AVOID_MENU_REDUNDANCY=true)
TEXI2INFO_FLAGS =
%.pdf: %.texi
$(TEXI2DVI) --pdf $(TEXI2PDF_FLAGS) -o $@ $<
%.html: %.texi
$(MAKEINFO) --html $(TEXI2HTML_FLAGS) -o $@ $<
%.info: %.texi
$(MAKEINFO) $(TEXI2INFO_FLAGS) -o $@ $<
# Static code analysis: Run Coverity.
COVERITY ?= cov-build
COVERITY_DIR ?= cov-int
COVERITY_SOURCES ?= $(CURDIR)
.PHONY: coverity
coverity:
rm -rf $(COVERITY_DIR)
$(COVERITY) --dir $(COVERITY_DIR) $(MAKE) -C $(COVERITY_SOURCES)
tar czf $(COVERITY_DIR).tgz $(COVERITY_DIR)
# Static code analysis: Run cppcheck on the source code tree starting at current directory.
# In debug mode, the diagnostics are more aggressive but may be false positive.
CPPCHECK ?= cppcheck
CPPCHECK_SOURCES ?= $(CURDIR)
CPPCHECK_FLAGS += $(CXXFLAGS_INCLUDES) --inline-suppr --quiet --force \
--template="{file}:{line}: ({severity}) {id}: {message}" \
--enable=all --suppress=unusedFunction --suppress=missingIncludeSystem \
$(if $(DEBUG),--inconclusive,)
.PHONY: cppcheck cppcheck-xml
cppcheck:
$(CPPCHECK) $(CPPCHECK_FLAGS) $(CPPCHECK_SOURCES)
cppcheck-xml:
$(CPPCHECK) $(CPPCHECK_FLAGS) --xml --xml-version=2 $(CPPCHECK_SOURCES)
# Static code analysis: Run flawfinder on the source code tree starting at current directory.
FLAWFINDER ?= flawfinder
FLAWFINDER_SOURCES ?= $(CURDIR)
FLAWFINDER_FLAGS += --quiet --dataonly
.PHONY: flawfinder
flawfinder:
$(FLAWFINDER) $(FLAWFINDER_FLAGS) $(FLAWFINDER_SOURCES)
# Static code analysis: Run scan-build on the source code tree starting at current directory.
SCANBUILD ?= scan-build
SCANBUILD_SOURCES ?= $(CURDIR)
SCANBUILD_FLAGS += -o $(OBJDIR)
.PHONY: scan-build
scan-build:
$(SCANBUILD) $(SCANBUILD_FLAGS) $(MAKE) -C $(SCANBUILD_SOURCES)
# Utilities: display predefined macros for C and C++
.PHONY: cmacros cxxmacros
cmacros:
@$(CPP) -x c -dM /dev/null | sort
cxxmacros:
@$(CPP) -x c++ -dM /dev/null | sort
# Cleanup Windows oddities in source files.
# Many IDE's indent with tabs, and tabs are 4 chars wide.
# Tabs shall not be expanded in Makefiles.
.PHONY: unixify
unixify:
for f in $$(find . -name \*.c -o -name \*.cpp -o -name \*.h -o -name \*.sh -o -name \*.dox -o -name \*.md -o -name \*.xml -o -name \*.txt); do \
expand -t 4 $$f >$$f.tmp; \
chmod --reference=$$f $$f.tmp; \
mv -f $$f.tmp $$f; \
done
for f in $$(find . -name \*.c -o -name \*.cpp -o -name \*.h -o -name Makefile\* -o -name \*.sh -o -name \*.dox -o -name \*.md -o -name \*.xml -o -name \*.txt); do \
dos2unix -q $$f; \
sed -i -e 's/ *$$//' $$f; \
done
# Display make variables for debug purposes.
.PHONY: listvars
listvars:
@true
$(foreach v, \
$(sort $(filter-out .% ^% @% _% *% \%% <% +% ?% BASH% LS_COLORS SSH% VTE% XDG%,$(.VARIABLES))), \
$(info $(v) = "$($(v))"))