• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.PHONY: pretty clean ChangeLog.md release
2
3##########################################################################
4# configuration
5##########################################################################
6
7# directory to recent compiler binaries
8COMPILER_DIR=/Users/niels/Documents/projects/compilers/local/bin
9
10# find GNU sed to use `-i` parameter
11SED:=$(shell command -v gsed || which sed)
12
13
14##########################################################################
15# source files
16##########################################################################
17
18# the list of sources in the include folder
19SRCS=$(shell find include -type f | sort)
20
21# the single header (amalgamated from the source files)
22AMALGAMATED_FILE=single_include/nlohmann/json.hpp
23
24
25##########################################################################
26# documentation of the Makefile's targets
27##########################################################################
28
29# main target
30all:
31	@echo "amalgamate - amalgamate file single_include/nlohmann/json.hpp from the include/nlohmann sources"
32	@echo "ChangeLog.md - generate ChangeLog file"
33	@echo "check - compile and execute test suite"
34	@echo "check-amalgamation - check whether sources have been amalgamated"
35	@echo "check-fast - compile and execute test suite (skip long-running tests)"
36	@echo "clean - remove built files"
37	@echo "coverage - create coverage information with lcov"
38	@echo "coverage-fast - create coverage information with fastcov"
39	@echo "cppcheck - analyze code with cppcheck"
40	@echo "cpplint - analyze code with cpplint"
41	@echo "clang_tidy - analyze code with Clang-Tidy"
42	@echo "clang_analyze - analyze code with Clang-Analyzer"
43	@echo "doctest - compile example files and check their output"
44	@echo "fuzz_testing - prepare fuzz testing of the JSON parser"
45	@echo "fuzz_testing_bson - prepare fuzz testing of the BSON parser"
46	@echo "fuzz_testing_cbor - prepare fuzz testing of the CBOR parser"
47	@echo "fuzz_testing_msgpack - prepare fuzz testing of the MessagePack parser"
48	@echo "fuzz_testing_ubjson - prepare fuzz testing of the UBJSON parser"
49	@echo "json_unit - create single-file test executable"
50	@echo "pedantic_clang - run Clang with maximal warning flags"
51	@echo "pedantic_gcc - run GCC with maximal warning flags"
52	@echo "pretty - beautify code with Artistic Style"
53	@echo "run_benchmarks - build and run benchmarks"
54
55
56##########################################################################
57# unit tests
58##########################################################################
59
60# build unit tests
61json_unit:
62	@$(MAKE) json_unit -C test
63
64# run unit tests
65check:
66	$(MAKE) check -C test
67
68# run unit tests and skip expensive tests
69check-fast:
70	$(MAKE) check -C test TEST_PATTERN=""
71
72
73##########################################################################
74# coverage
75##########################################################################
76
77coverage:
78	rm -fr build_coverage
79	mkdir build_coverage
80	cd build_coverage ; CXX=g++-8 cmake .. -GNinja -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON
81	cd build_coverage ; ninja
82	cd build_coverage ; ctest -E '.*_default' -j10
83	cd build_coverage ; ninja lcov_html
84	open build_coverage/test/html/index.html
85
86coverage-fast:
87	rm -fr build_coverage
88	mkdir build_coverage
89	cd build_coverage ; CXX=g++-9 cmake .. -GNinja -DJSON_Coverage=ON -DJSON_MultipleHeaders=ON
90	cd build_coverage ; ninja
91	cd build_coverage ; ctest -E '.*_default' -j10
92	cd build_coverage ; ninja fastcov_html
93	open build_coverage/test/html/index.html
94
95##########################################################################
96# documentation tests
97##########################################################################
98
99# compile example files and check output
100doctest:
101	$(MAKE) check_output -C doc
102
103
104##########################################################################
105# warning detector
106##########################################################################
107
108# calling Clang with all warnings, except:
109# -Wno-c++2a-compat: u8 literals will behave differently in C++20...
110# -Wno-deprecated-declarations: the library deprecated some functions
111# -Wno-documentation-unknown-command: code uses user-defined commands like @complexity
112# -Wno-exit-time-destructors: warning in json code triggered by NLOHMANN_JSON_SERIALIZE_ENUM
113# -Wno-float-equal: not all comparisons in the tests can be replaced by Approx
114# -Wno-keyword-macro: unit-tests use "#define private public"
115# -Wno-padded: padding is nothing to warn about
116# -Wno-range-loop-analysis: items tests "for(const auto i...)"
117# -Wno-switch-enum -Wno-covered-switch-default: pedantic/contradicting warnings about switches
118# -Wno-weak-vtables: exception class is defined inline, but has virtual method
119pedantic_clang:
120	$(MAKE) json_unit CXX=c++ CXXFLAGS=" \
121		-std=c++11 -Wno-c++98-compat -Wno-c++98-compat-pedantic \
122		-Werror \
123		-Weverything \
124		-Wno-c++2a-compat \
125		-Wno-deprecated-declarations \
126		-Wno-documentation-unknown-command \
127		-Wno-exit-time-destructors \
128		-Wno-float-equal \
129		-Wno-keyword-macro \
130		-Wno-padded \
131		-Wno-range-loop-analysis \
132		-Wno-switch-enum -Wno-covered-switch-default \
133		-Wno-weak-vtables"
134
135# calling GCC with most warnings
136pedantic_gcc:
137	$(MAKE) json_unit CXX=/usr/local/bin/g++-9 CXXFLAGS=" \
138		-std=c++11 \
139		-Waddress \
140		-Waddress-of-packed-member \
141		-Waggressive-loop-optimizations \
142		-Waligned-new=all \
143		-Wall \
144		-Walloc-zero \
145		-Walloca \
146		-Warray-bounds \
147		-Warray-bounds=2 \
148		-Wattribute-alias=2 \
149		-Wattribute-warning \
150		-Wattributes \
151		-Wbool-compare \
152		-Wbool-operation \
153		-Wbuiltin-declaration-mismatch \
154		-Wbuiltin-macro-redefined \
155		-Wcannot-profile \
156		-Wcast-align \
157		-Wcast-function-type \
158		-Wcast-qual \
159		-Wcatch-value=3 \
160		-Wchar-subscripts \
161		-Wclass-conversion \
162		-Wclass-memaccess \
163		-Wclobbered \
164		-Wcomment \
165		-Wcomments \
166		-Wconditionally-supported \
167		-Wconversion \
168		-Wconversion-null \
169		-Wcoverage-mismatch \
170		-Wcpp \
171		-Wctor-dtor-privacy \
172		-Wdangling-else \
173		-Wdate-time \
174		-Wdelete-incomplete \
175		-Wdelete-non-virtual-dtor \
176		-Wdeprecated \
177		-Wdeprecated-copy \
178		-Wdeprecated-copy-dtor \
179		-Wdeprecated-declarations \
180		-Wdisabled-optimization \
181		-Wdiv-by-zero \
182		-Wdouble-promotion \
183		-Wduplicated-branches \
184		-Wduplicated-cond \
185		-Weffc++ \
186		-Wempty-body \
187		-Wendif-labels \
188		-Wenum-compare \
189		-Wexpansion-to-defined \
190		-Werror \
191		-Wextra \
192		-Wextra-semi \
193		-Wfloat-conversion \
194		-Wformat \
195		-Wformat-contains-nul \
196		-Wformat-extra-args \
197		-Wformat-nonliteral \
198		-Wformat-overflow=2 \
199		-Wformat-security \
200		-Wformat-signedness \
201		-Wformat-truncation=2 \
202		-Wformat-y2k \
203		-Wformat-zero-length \
204		-Wformat=2 \
205		-Wframe-address \
206		-Wfree-nonheap-object \
207		-Whsa \
208		-Wif-not-aligned \
209		-Wignored-attributes \
210		-Wignored-qualifiers \
211		-Wimplicit-fallthrough=5 \
212		-Winherited-variadic-ctor \
213		-Winit-list-lifetime \
214		-Winit-self \
215		-Winline \
216		-Wint-in-bool-context \
217		-Wint-to-pointer-cast \
218		-Winvalid-memory-model \
219		-Winvalid-offsetof \
220		-Winvalid-pch \
221		-Wliteral-suffix \
222		-Wlogical-not-parentheses \
223		-Wlogical-op \
224		-Wlto-type-mismatch \
225		-Wmain \
226		-Wmaybe-uninitialized \
227		-Wmemset-elt-size \
228		-Wmemset-transposed-args \
229		-Wmisleading-indentation \
230		-Wmissing-attributes \
231		-Wmissing-braces \
232		-Wmissing-declarations \
233		-Wmissing-field-initializers \
234		-Wmissing-format-attribute \
235		-Wmissing-include-dirs \
236		-Wmissing-noreturn \
237		-Wmissing-profile \
238		-Wmultichar \
239		-Wmultiple-inheritance \
240		-Wmultistatement-macros \
241		-Wnarrowing \
242		-Wno-deprecated-declarations \
243		-Wno-float-equal \
244		-Wno-long-long \
245		-Wno-namespaces \
246		-Wno-padded \
247		-Wno-switch-enum \
248		-Wno-system-headers \
249		-Wno-templates \
250		-Wno-undef \
251		-Wnoexcept \
252		-Wnoexcept-type \
253		-Wnon-template-friend \
254		-Wnon-virtual-dtor \
255		-Wnonnull \
256		-Wnonnull-compare \
257		-Wnonportable-cfstrings \
258		-Wnormalized \
259		-Wnull-dereference \
260		-Wodr \
261		-Wold-style-cast \
262		-Wopenmp-simd \
263		-Woverflow \
264		-Woverlength-strings \
265		-Woverloaded-virtual \
266		-Wpacked \
267		-Wpacked-bitfield-compat \
268		-Wpacked-not-aligned \
269		-Wparentheses \
270		-Wpedantic \
271		-Wpessimizing-move \
272		-Wplacement-new=2 \
273		-Wpmf-conversions \
274		-Wpointer-arith \
275		-Wpointer-compare \
276		-Wpragmas \
277		-Wprio-ctor-dtor \
278		-Wpsabi \
279		-Wredundant-decls \
280		-Wredundant-move \
281		-Wregister \
282		-Wreorder \
283		-Wrestrict \
284		-Wreturn-local-addr \
285		-Wreturn-type \
286		-Wscalar-storage-order \
287		-Wsequence-point \
288		-Wshadow \
289		-Wshadow-compatible-local \
290		-Wshadow-local \
291		-Wshadow=compatible-local \
292		-Wshadow=global \
293		-Wshadow=local \
294		-Wshift-count-negative \
295		-Wshift-count-overflow \
296		-Wshift-negative-value \
297		-Wshift-overflow=2 \
298		-Wsign-compare \
299		-Wsign-conversion \
300		-Wsign-promo \
301		-Wsized-deallocation \
302		-Wsizeof-array-argument \
303		-Wsizeof-pointer-div \
304		-Wsizeof-pointer-memaccess \
305		-Wstack-protector \
306		-Wstrict-aliasing=3 \
307		-Wstrict-null-sentinel \
308		-Wstrict-overflow=5 \
309		-Wstringop-overflow=4 \
310		-Wstringop-truncation \
311		-Wsubobject-linkage \
312		-Wsuggest-attribute=cold \
313		-Wsuggest-attribute=const \
314		-Wsuggest-attribute=format \
315		-Wsuggest-attribute=malloc \
316		-Wsuggest-attribute=noreturn \
317		-Wsuggest-attribute=pure \
318		-Wsuggest-final-methods \
319		-Wsuggest-final-types \
320		-Wsuggest-override \
321		-Wswitch \
322		-Wswitch-bool \
323		-Wswitch-default \
324		-Wswitch-unreachable \
325		-Wsync-nand \
326		-Wsynth \
327		-Wtautological-compare \
328		-Wterminate \
329		-Wtrampolines \
330		-Wtrigraphs \
331		-Wtype-limits \
332		-Wuninitialized \
333		-Wunknown-pragmas \
334		-Wunreachable-code \
335		-Wunsafe-loop-optimizations \
336		-Wunused \
337		-Wunused-but-set-parameter \
338		-Wunused-but-set-variable \
339		-Wunused-const-variable=2 \
340		-Wunused-function \
341		-Wunused-label \
342		-Wunused-local-typedefs \
343		-Wunused-macros \
344		-Wunused-parameter \
345		-Wunused-result \
346		-Wunused-value \
347		-Wunused-variable \
348		-Wuseless-cast \
349		-Wvarargs \
350		-Wvariadic-macros \
351		-Wvector-operation-performance \
352		-Wvirtual-inheritance \
353		-Wvirtual-move-assign \
354		-Wvla \
355		-Wvolatile-register-var \
356		-Wwrite-strings \
357		-Wzero-as-null-pointer-constant \
358		"
359
360##########################################################################
361# benchmarks
362##########################################################################
363
364run_benchmarks:
365	rm -fr build_benchmarks
366	mkdir build_benchmarks
367	cd build_benchmarks ; cmake ../benchmarks -GNinja -DCMAKE_BUILD_TYPE=Release
368	cd build_benchmarks ; ninja
369	cd build_benchmarks ; ./json_benchmarks
370
371##########################################################################
372# fuzzing
373##########################################################################
374
375# the overall fuzz testing target
376fuzz_testing:
377	rm -fr fuzz-testing
378	mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out
379	$(MAKE) parse_afl_fuzzer -C test CXX=afl-clang++
380	mv test/parse_afl_fuzzer fuzz-testing/fuzzer
381	find test/data/json_tests -size -5k -name *json | xargs -I{} cp "{}" fuzz-testing/testcases
382	@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
383
384fuzz_testing_bson:
385	rm -fr fuzz-testing
386	mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out
387	$(MAKE) parse_bson_fuzzer -C test CXX=afl-clang++
388	mv test/parse_bson_fuzzer fuzz-testing/fuzzer
389	find test/data -size -5k -name *.bson | xargs -I{} cp "{}" fuzz-testing/testcases
390	@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
391
392fuzz_testing_cbor:
393	rm -fr fuzz-testing
394	mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out
395	$(MAKE) parse_cbor_fuzzer -C test CXX=afl-clang++
396	mv test/parse_cbor_fuzzer fuzz-testing/fuzzer
397	find test/data -size -5k -name *.cbor | xargs -I{} cp "{}" fuzz-testing/testcases
398	@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
399
400fuzz_testing_msgpack:
401	rm -fr fuzz-testing
402	mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out
403	$(MAKE) parse_msgpack_fuzzer -C test CXX=afl-clang++
404	mv test/parse_msgpack_fuzzer fuzz-testing/fuzzer
405	find test/data -size -5k -name *.msgpack | xargs -I{} cp "{}" fuzz-testing/testcases
406	@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
407
408fuzz_testing_ubjson:
409	rm -fr fuzz-testing
410	mkdir -p fuzz-testing fuzz-testing/testcases fuzz-testing/out
411	$(MAKE) parse_ubjson_fuzzer -C test CXX=afl-clang++
412	mv test/parse_ubjson_fuzzer fuzz-testing/fuzzer
413	find test/data -size -5k -name *.ubjson | xargs -I{} cp "{}" fuzz-testing/testcases
414	@echo "Execute: afl-fuzz -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer"
415
416fuzzing-start:
417	afl-fuzz -S fuzzer1 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &
418	afl-fuzz -S fuzzer2 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &
419	afl-fuzz -S fuzzer3 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &
420	afl-fuzz -S fuzzer4 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &
421	afl-fuzz -S fuzzer5 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &
422	afl-fuzz -S fuzzer6 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &
423	afl-fuzz -S fuzzer7 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer > /dev/null &
424	afl-fuzz -M fuzzer0 -i fuzz-testing/testcases -o fuzz-testing/out fuzz-testing/fuzzer
425
426fuzzing-stop:
427	-killall fuzzer
428	-killall afl-fuzz
429
430
431##########################################################################
432# Static analysis
433##########################################################################
434
435# call cppcheck <http://cppcheck.sourceforge.net>
436# Note: this target is called by Travis
437cppcheck:
438	cppcheck --enable=warning --inline-suppr --inconclusive --force --std=c++11 $(AMALGAMATED_FILE) --error-exitcode=1
439
440# call Clang Static Analyzer <https://clang-analyzer.llvm.org>
441clang_analyze:
442	rm -fr clang_analyze_build
443	mkdir clang_analyze_build
444	cd clang_analyze_build ; CCC_CXX=$(COMPILER_DIR)/clang++ CXX=$(COMPILER_DIR)/clang++ $(COMPILER_DIR)/scan-build cmake .. -GNinja
445	cd clang_analyze_build ; \
446		$(COMPILER_DIR)/scan-build \
447			-enable-checker alpha.core.BoolAssignment,alpha.core.CallAndMessageUnInitRefArg,alpha.core.CastSize,alpha.core.CastToStruct,alpha.core.Conversion,alpha.core.DynamicTypeChecker,alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,alpha.core.SizeofPtr,alpha.core.StackAddressAsyncEscape,alpha.core.TestAfterDivZero,alpha.deadcode.UnreachableCode,core.builtin.BuiltinFunctions,core.builtin.NoReturnFunctions,core.CallAndMessage,core.DivideZero,core.DynamicTypePropagation,core.NonnilStringConstants,core.NonNullParamChecker,core.NullDereference,core.StackAddressEscape,core.UndefinedBinaryOperatorResult,core.uninitialized.ArraySubscript,core.uninitialized.Assign,core.uninitialized.Branch,core.uninitialized.CapturedBlockVariable,core.uninitialized.UndefReturn,core.VLASize,cplusplus.InnerPointer,cplusplus.Move,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,cplusplus.SelfAssignment,deadcode.DeadStores,nullability.NullableDereferenced,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull \
448			--use-c++=$(COMPILER_DIR)/clang++ -analyze-headers -o report ninja
449	open clang_analyze_build/report/*/index.html
450
451# call cpplint <https://github.com/cpplint/cpplint>
452# Note: some errors expected due to false positives
453cpplint:
454	third_party/cpplint/cpplint.py \
455		--filter=-whitespace,-legal,-readability/alt_tokens,-runtime/references,-runtime/explicit \
456		--quiet --recursive $(SRCS)
457
458# call Clang-Tidy <https://clang.llvm.org/extra/clang-tidy/>
459clang_tidy:
460	$(COMPILER_DIR)/clang-tidy $(AMALGAMATED_FILE) -- -Iinclude -std=c++11
461
462# call PVS-Studio Analyzer <https://www.viva64.com/en/pvs-studio/>
463pvs_studio:
464	rm -fr pvs_studio_build
465	mkdir pvs_studio_build
466	cd pvs_studio_build ; cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=On
467	cd pvs_studio_build ; pvs-studio-analyzer analyze -j 10
468	cd pvs_studio_build ; plog-converter -a'GA:1,2;64:1;CS' -t fullhtml PVS-Studio.log -o pvs
469	open pvs_studio_build/pvs/index.html
470
471# call Infer <https://fbinfer.com> static analyzer
472infer:
473	rm -fr infer_build
474	mkdir infer_build
475	cd infer_build ; infer compile -- cmake .. ; infer run -- make -j 4
476
477# call OCLint <http://oclint.org> static analyzer
478oclint:
479	oclint $(SRCS) -report-type html -enable-global-analysis -o oclint_report.html -max-priority-1=10000 -max-priority-2=10000 -max-priority-3=10000 -- -std=c++11 -Iinclude
480	open oclint_report.html
481
482# execute the test suite with Clang sanitizers (address and undefined behavior)
483clang_sanitize:
484	rm -fr clang_sanitize_build
485	mkdir clang_sanitize_build
486	cd clang_sanitize_build ; CXX=$(COMPILER_DIR)/clang++ cmake .. -DJSON_Sanitizer=On -DJSON_MultipleHeaders=ON -GNinja
487	cd clang_sanitize_build ; ninja
488	cd clang_sanitize_build ; ctest -E '.*_default' -j10
489
490
491##########################################################################
492# Code format and source amalgamation
493##########################################################################
494
495# call the Artistic Style pretty printer on all source files
496pretty:
497	astyle \
498		--style=allman \
499		--indent=spaces=4 \
500		--indent-modifiers \
501	    --indent-switches \
502	    --indent-preproc-block \
503	    --indent-preproc-define \
504	    --indent-col1-comments \
505	    --pad-oper \
506	    --pad-header \
507	    --align-pointer=type \
508	    --align-reference=type \
509	    --add-brackets \
510	    --convert-tabs \
511	    --close-templates \
512	    --lineend=linux \
513	    --preserve-date \
514	    --suffix=none \
515	    --formatted \
516	   $(SRCS) $(AMALGAMATED_FILE) test/src/*.cpp benchmarks/src/benchmarks.cpp doc/examples/*.cpp
517
518# create single header file
519amalgamate: $(AMALGAMATED_FILE)
520
521# call the amalgamation tool and pretty print
522$(AMALGAMATED_FILE): $(SRCS)
523	third_party/amalgamate/amalgamate.py -c third_party/amalgamate/config.json -s . --verbose=yes
524	$(MAKE) pretty
525
526# check if file single_include/nlohmann/json.hpp has been amalgamated from the nlohmann sources
527# Note: this target is called by Travis
528check-amalgamation:
529	@mv $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~
530	@$(MAKE) amalgamate
531	@diff $(AMALGAMATED_FILE) $(AMALGAMATED_FILE)~ || (echo "===================================================================\n  Amalgamation required! Please read the contribution guidelines\n  in file .github/CONTRIBUTING.md.\n===================================================================" ; mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE) ; false)
532	@mv $(AMALGAMATED_FILE)~ $(AMALGAMATED_FILE)
533
534# check if every header in nlohmann includes sufficient headers to be compiled individually
535check-single-includes:
536	@for x in $(SRCS); do \
537	  echo "Checking self-sufficiency of $$x..." ; \
538	  echo "#include <$$x>\nint main() {}\n" | sed 's|include/||' > single_include_test.cpp; \
539	  $(CXX) $(CXXFLAGS) -Iinclude -std=c++11 single_include_test.cpp -o single_include_test; \
540	  rm -f single_include_test.cpp single_include_test; \
541	done
542
543
544##########################################################################
545# CMake
546##########################################################################
547
548# grep "^option" CMakeLists.txt test/CMakeLists.txt | sed 's/(/ /' | awk '{print $2}' | xargs
549
550# check if all flags of our CMake files work
551check_cmake_flags_do:
552	$(CMAKE_BINARY) --version
553	for flag in '' JSON_BuildTests JSON_Install JSON_MultipleHeaders JSON_Sanitizer JSON_Valgrind JSON_NoExceptions JSON_Coverage; do \
554		rm -fr cmake_build; \
555		mkdir cmake_build; \
556		echo "$(CMAKE_BINARY) .. -D$$flag=On" ; \
557		cd cmake_build ; \
558		CXX=g++-8 $(CMAKE_BINARY) .. -D$$flag=On -DCMAKE_CXX_COMPILE_FEATURES="cxx_std_11;cxx_range_for" -DCMAKE_CXX_FLAGS="-std=gnu++11" ; \
559		test -f Makefile || exit 1 ; \
560		cd .. ; \
561	done;
562
563# call target `check_cmake_flags_do` twice: once for minimal required CMake version 3.1.0 and once for the installed version
564check_cmake_flags:
565	wget https://github.com/Kitware/CMake/releases/download/v3.1.0/cmake-3.1.0-Darwin64.tar.gz
566	tar xfz cmake-3.1.0-Darwin64.tar.gz
567	CMAKE_BINARY=$(abspath cmake-3.1.0-Darwin64/CMake.app/Contents/bin/cmake) $(MAKE) check_cmake_flags_do
568	CMAKE_BINARY=$(shell which cmake) $(MAKE) check_cmake_flags_do
569
570
571##########################################################################
572# ChangeLog
573##########################################################################
574
575# Create a ChangeLog based on the git log using the GitHub Changelog Generator
576# (<https://github.com/github-changelog-generator/github-changelog-generator>).
577
578# variable to control the diffs between the last released version and the current repository state
579NEXT_VERSION ?= "unreleased"
580
581ChangeLog.md:
582	github_changelog_generator -o ChangeLog.md --simple-list --release-url https://github.com/nlohmann/json/releases/tag/%s --future-release $(NEXT_VERSION)
583	$(SED) -i 's|https://github.com/nlohmann/json/releases/tag/HEAD|https://github.com/nlohmann/json/tree/HEAD|' ChangeLog.md
584	$(SED) -i '2i All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).' ChangeLog.md
585
586
587##########################################################################
588# Release files
589##########################################################################
590
591# Create the files for a release and add signatures and hashes. We use `-X` to make the resulting ZIP file
592# reproducible, see <https://content.pivotal.io/blog/barriers-to-deterministic-reproducible-zip-files>.
593
594release:
595	rm -fr release_files
596	mkdir release_files
597	zip -9 --recurse-paths -X include.zip $(SRCS) $(AMALGAMATED_FILE) meson.build
598	gpg --armor --detach-sig include.zip
599	mv include.zip include.zip.asc release_files
600	gpg --armor --detach-sig $(AMALGAMATED_FILE)
601	cp $(AMALGAMATED_FILE) release_files
602	mv $(AMALGAMATED_FILE).asc release_files
603	cd release_files ; shasum -a 256 json.hpp > hashes.txt
604	cd release_files ; shasum -a 256 include.zip >> hashes.txt
605
606
607##########################################################################
608# Maintenance
609##########################################################################
610
611# clean up
612clean:
613	rm -fr json_unit json_benchmarks fuzz fuzz-testing *.dSYM test/*.dSYM oclint_report.html
614	rm -fr benchmarks/files/numbers/*.json
615	rm -fr cmake-3.1.0-Darwin64.tar.gz cmake-3.1.0-Darwin64
616	rm -fr build_coverage build_benchmarks fuzz-testing clang_analyze_build pvs_studio_build infer_build clang_sanitize_build cmake_build
617	$(MAKE) clean -Cdoc
618	$(MAKE) clean -Ctest
619
620##########################################################################
621# Thirdparty code
622##########################################################################
623
624update_hedley:
625	rm -f include/nlohmann/thirdparty/hedley/hedley.hpp include/nlohmann/thirdparty/hedley/hedley_undef.hpp
626	curl https://raw.githubusercontent.com/nemequ/hedley/master/hedley.h -o include/nlohmann/thirdparty/hedley/hedley.hpp
627	gsed -i 's/HEDLEY_/JSON_HEDLEY_/g' include/nlohmann/thirdparty/hedley/hedley.hpp
628	grep "[[:blank:]]*#[[:blank:]]*undef" include/nlohmann/thirdparty/hedley/hedley.hpp | grep -v "__" | sort | uniq | gsed 's/ //g' | gsed 's/undef/undef /g' > include/nlohmann/thirdparty/hedley/hedley_undef.hpp
629	$(MAKE) amalgamate
630