comparison mupdf-source/thirdparty/extract/Makefile @ 3:2c135c81b16c

MERGE: upstream PyMuPDF 1.26.4 with MuPDF 1.26.7
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:44:09 +0200
parents b50eed0cc0ef
children
comparison
equal deleted inserted replaced
0:6015a75abc2d 3:2c135c81b16c
1 # Example commands:
2 #
3 # make
4 # make test
5 # Runs all tests.
6 #
7 # make test-exe
8 # Runs exe regression tests. These use $(gs) and $(mutool) to generate
9 # intermediate data about pdf content, then uses $(exe) to convert to
10 # docx.
11 #
12 # make test-mutool
13 # Runs mutool regression tests. This uses $(mutool) to convert directly
14 # from pdf to docx. We require that $(mutool) was built with extract=yes.
15 #
16 # make test-gs
17 # Runs gs regression tests. This uses $(gs) to convert directly from pdf
18 # to docx. We require that $(gs) was built with --with-extract-dir=... We
19 # also do a simple test of output-file-per-page.
20 #
21 # make test-tables
22 # Tests handling of tables, using mutool with docx device's html output.
23 #
24 # make test-buffer test-misc test-src
25 # Runs unit tests etc.
26 #
27 # make build=debug-opt ...
28 # Set build flags.
29 #
30 # make build=memento msqueeze
31 # Run memento squeeze test.
32 #
33 # Assuming we are in mupdf/thirdparty/extract, and there is a ghostpdl at
34 # the same level as mupdf, with a softlink from ghostpdl to extract:
35 #
36 # make test-rebuild-dependent-binaries
37 # Clean/Configure/Rebuild the required mupdf and gs binaries.
38 #
39 # make test-build-dependent-binaries
40 # Build the required mupdf and gs binaries.
41
42
43 # Build flags.
44 #
45 # Note that OpenBSD's clang-8 appears to ignore -Wdeclaration-after-statement.
46 #
47 build = debug
48
49 flags_link = -W -Wall -lm
50 flags_compile = -W -Wall -Wextra -Wpointer-sign -Wmissing-declarations -Wmissing-prototypes -Wdeclaration-after-statement -Wpointer-arith -Wconversion -Wno-sign-conversion -Werror -MMD -MP -Iinclude -Isrc
51
52 uname = $(shell uname)
53
54 ifeq ($(build),)
55 $(error Need to specify build=debug|opt|debug-opt|memento)
56 else ifeq ($(build),debug)
57 flags_link += -g
58 flags_compile += -g
59 else ifeq ($(build),opt)
60 flags_link += -O2
61 flags_compile += -O2
62 else ifeq ($(build),debug-opt)
63 flags_link += -g -O2
64 flags_compile += -g -O2
65 else ifeq ($(build),memento)
66 flags_link += -g -dl
67 ifeq ($(uname),OpenBSD)
68 flags_link += -l execinfo
69 endif
70 flags_compile += -g -D MEMENTO
71 else
72 $(error unrecognised $$(build)=$(build))
73 endif
74
75 regenerate ?= no
76 ifeq ($(regenerate),yes)
77 DIFF_OR_CP = rm -rf $(word 2,%$^); cp -r
78 else
79 DIFF_OR_CP = diff -ru
80 endif
81
82 gdb = gdb
83 ifeq ($(uname),OpenBSD)
84 flags_link += -L /usr/local/lib -l execinfo
85 $(warning have added -L /usr/local/lib)
86 gdb = egdb
87 # For some reason OpenBSD's gmake defaults CXX to g++, which is not helpful.
88 CXX = c++
89 endif
90
91 # Locations of mutool and gs. By default we assume these are not available.
92 #
93 # If this extract checkout is within a mupdf tree (typically as a git
94 # submodule) we assume ghostpdl is checked out nearby and both mutool gs and gs
95 # binaries are available and built with extract enabled.
96 #
97 # Disable this by running: make we_are_mupdf_thirdparty= ...
98 #
99 we_are_mupdf_thirdparty = $(findstring /mupdf/thirdparty/extract, $(abspath .))
100 ifneq ($(we_are_mupdf_thirdparty),)
101 $(warning we are mupdf thirdparty)
102 ifeq ($(build),memento)
103 mutool := ../../build/memento/mutool
104 else
105 mutool := ../../build/debug/mutool
106 endif
107 gs := ../../../ghostpdl/debug-extract-bin/gs
108 libbacktrace = ../../../libbacktrace/.libs
109 endif
110
111 # If mutool/gs are specified, they must exist.
112 #
113 ifneq ($(mutool),)
114 ifeq ($(wildcard $(mutool)),)
115 $(error mutool does not exist: $(mutool))
116 endif
117 $(warning mutool=$(mutool))
118 endif
119
120 ifeq ($(build),memento)
121 mutool_run := MEMENTO_ABORT_ON_LEAK=1 $(mutool)
122 else
123 mutool_run := $(mutool)
124 endif
125
126 ifneq ($(gs),)
127 ifeq ($(wildcard $(gs)),)
128 $(error gs does not exist: $(gs))
129 endif
130 $(warning gs=$(gs))
131 endif
132
133
134 # Default target - run all tests.
135 #
136 test: test-buffer test-misc test-src test-exe test-mutool test-gs test-html test-tables
137 @echo $@: passed
138
139 # Define the main test targets.
140 #
141 # test/Python2clipped.pdf is same as test/Python2.pdf except it as a modified
142 # MediaBox that excludes some glyphs.
143 #
144 pdfs = test/Python2.pdf test/Python2clipped.pdf test/zlib.3.pdf test/text_graphic_image.pdf
145 pdfs_generated = $(patsubst test/%, test/generated/%, $(pdfs))
146
147 tests_exe := \
148 $(patsubst %, %.extract.docx, $(tests_exe)) \
149 $(patsubst %, %.extract-rotate.docx, $(tests_exe)) \
150 $(patsubst %, %.extract-rotate-spacing.docx, $(tests_exe)) \
151 $(patsubst %, %.extract-autosplit.docx, $(tests_exe)) \
152 $(patsubst %, %.extract-template.docx, $(tests_exe)) \
153
154 tests_exe := $(patsubst %, %.diff, $(tests_exe))
155
156 ifneq ($(mutool),)
157 # Targets that test direct conversion with mutool.
158 #
159 tests_mutool := \
160 $(patsubst %, %.mutool.docx.dir.diff, $(pdfs_generated)) \
161 $(patsubst %, %.mutool-norotate.docx.dir.diff, $(pdfs_generated)) \
162 $(patsubst %, %.mutool.odt.dir.diff, $(pdfs_generated)) \
163 $(patsubst %, %.mutool.text.diff, $(pdfs_generated)) \
164
165 tests_mutool_odt := \
166 $(patsubst %, %.mutool.odt.diff, $(pdfs_generated)) \
167
168 tests_mutool_text := \
169 $(patsubst %, %.mutool.text.diff, $(pdfs_generated)) \
170
171 tests_html := test/generated/table.pdf.mutool.html.diff
172 endif
173 ifneq ($(gs),)
174 # Targets that test direct conversion with gs.
175 #
176 tests_gs := \
177 $(patsubst %, %.gs.docx.dir.diff, $(pdfs_generated)) \
178 test_gs_fpp
179
180 # We don't yet do clipping with gs so exclude Python2clipped.pdf.*:
181 tests_gs := $(filter-out test/generated/Python2clipped.pdf.%, $(tests_gs))
182
183 #$(warning tests_gs: $(tests_gs))
184 endif
185 #$(warning $(tests))
186
187 test-exe: $(tests_exe)
188 @echo $@: passed
189
190 # Checks output of mutool conversion from .pdf to .docx/.odt.
191 #
192 test-mutool: $(tests_mutool)
193 @echo $@: passed
194
195 # Checks output of mutool conversion from .pdf to .odt.
196 #
197 test-mutool-odt: $(tests_mutool_odt)
198 @echo $@: passed
199
200 # Checks output of mutool conversion from .pdf to .text.
201 #
202 test-mutool-text: $(tests_mutool_text)
203 @echo $@: passed
204
205 # Checks output of gs conversion from .pdf to .docx. Requires that gs was built
206 # with extract as a third-party library. As of 2021-02-10 this requires, for
207 # example ghostpdl/extract being a link to an extract checkout and configuring
208 # with --with-extract-dir=extract.
209 #
210 test-gs: $(tests_gs)
211 @echo $@: passed
212
213 # Check behaviour of gs when writing file-per-page.
214 #
215 test_gs_fpp: $(gs)
216 @echo
217 @echo == Testing gs file-page-page
218 rm test/generated/text_graphic_image.pdf.gs.*.docx || true
219 $(gs) -sDEVICE=docxwrite -o test/generated/Python2.pdf.gs.%i.docx test/Python2.pdf
220 rm test/generated/text_graphic_image.pdf.gs.*.docx || true
221 $(gs) -sDEVICE=docxwrite -o test/generated/zlib.3.pdf.gs.%i.docx test/zlib.3.pdf
222 rm test/generated/text_graphic_image.pdf.gs.*.docx || true
223 $(gs) -sDEVICE=docxwrite -o test/generated/text_graphic_image.pdf.gs.%i.docx test/text_graphic_image.pdf
224 @echo Checking for correct number of generated files.
225 ls -l test/generated/*.pdf.gs.*.docx
226 ls test/generated/text_graphic_image.pdf.gs.*.docx | wc -l | grep '^ *1$$'
227 ls test/generated/Python2.pdf.gs.*.docx | wc -l | grep '^ *1$$'
228 ls test/generated/zlib.3.pdf.gs.*.docx | wc -l | grep '^ *2$$'
229
230
231 test-html: $(tests_html)
232
233 test-rebuild-dependent-binaries:
234 @echo == Rebuilding gs and mupdf binaries
235 cd ../../../ghostpdl && ./autogen.sh --with-extract-dir=extract && make -j 8 debugclean DEBUGDIRPREFIX=debug-extract- && make -j 8 debug DEBUGDIRPREFIX=debug-extract-
236 cd ../.. && make -j 8 build=debug clean && make -j 8 build=debug
237
238 test-build-dependent-binaries:
239 @echo == Building gs and mupdf binaries
240 cd ../../../ghostpdl && make -j 8 debug DEBUGDIRPREFIX=debug-extract-
241 cd ../.. && make -j 8 build=debug
242
243
244 ifneq ($(mutool),)
245 test_tables_pdfs = \
246 test/agstat.pdf \
247 test/background_lines_1.pdf \
248 test/background_lines_2.pdf \
249 test/column_span_1.pdf \
250 test/column_span_2.pdf \
251 test/electoral_roll.pdf \
252 test/rotated.pdf \
253 test/row_span.pdf \
254 test/table.pdf \
255 test/twotables_1.pdf \
256 test/twotables_2.pdf \
257
258 test_tables_generated = $(patsubst test/%, test/generated/%, $(test_tables_pdfs))
259
260 test_tables_html = $(patsubst test/%.pdf, test/generated/%.pdf.mutool.html.diff, $(test_tables_pdfs))
261 test_tables_docx = $(patsubst test/%.pdf, test/generated/%.pdf.mutool.docx.dir.diff, $(test_tables_pdfs))
262 test_tables_odt = $(patsubst test/%.pdf, test/generated/%.pdf.mutool.odt.dir.diff, $(test_tables_pdfs))
263
264 test_tables = $(test_tables_html) $(test_tables_docx) $(test_tables_odt)
265 endif
266
267 test-tables-html: $(test_tables_html)
268 test-tables-docx: $(test_tables_docx)
269 test-tables-odt: $(test_tables_odt)
270
271 test-tables: $(test_tables)
272 @echo $@: passed
273
274 test/generated/%.pdf.mutool.html.diff: test/generated/%.pdf.mutool.html test/%.pdf.mutool.html.ref
275 @echo
276 @echo == Checking $<
277 $(DIFF_OR_CP) $^
278
279 test/generated/%.pdf.mutool.cv.html.diff: test/generated/%.pdf.mutool.cv.html test/%.pdf.mutool.html.ref
280 @echo
281 @echo == Checking $<
282 $(DIFF_OR_CP) $^
283
284 test/generated/%.pdf.mutool.cv.html: test/%.pdf $(mutool)
285 $(mutool) convert -O resolution=300 -o $<..png $<
286 EXTRACT_OPENCV_IMAGE_BASE=$< $(mutool_run) convert -F docx -O html -o $@ $<
287
288 test/generated/%.pdf.mutool.text.diff: test/generated/%.pdf.mutool.text test/%.pdf.mutool.text.ref
289 @echo
290 @echo == Checking $<
291 $(DIFF_OR_CP) $^
292
293
294 # Main executable.
295 #
296 exe = src/build/extract-$(build).exe
297 exe_src = \
298 src/alloc.c \
299 src/astring.c \
300 src/boxer.c \
301 src/buffer.c \
302 src/document.c \
303 src/docx.c \
304 src/docx_template.c \
305 src/extract-exe.c \
306 src/extract.c \
307 src/html.c \
308 src/join.c \
309 src/mem.c \
310 src/odt.c \
311 src/odt_template.c \
312 src/outf.c \
313 src/rect.c \
314 src/sys.c \
315 src/text.c \
316 src/xml.c \
317 src/zip.c \
318
319
320 ifeq ($(build),memento)
321 exe_src += src/memento.c
322 ifeq ($(uname),Linux)
323 flags_compile += -D HAVE_LIBDL
324 flags_link += -L $(libbacktrace) -l backtrace -l dl
325 endif
326 endif
327 exe_obj := $(exe_src)
328 exe_obj := $(patsubst src/%.c, src/build/%.c-$(build).o, $(exe_obj))
329 exe_obj := $(patsubst src/%.cpp, src/build/%.cpp-$(build).o, $(exe_obj))
330 exe_dep = $(exe_obj:.o=.d)
331 exe: $(exe)
332 $(exe): $(exe_obj)
333 $(CXX) $(flags_link) -o $@ $^ -lz -lm
334
335 run_exe = $(exe)
336 ifeq ($(build),memento)
337 ifeq ($(uname),Linux)
338 run_exe = MEMENTO_ABORT_ON_LEAK=1 MEMENTO_HIDE_MULTIPLE_REALLOCS=1 LD_LIBRARY_PATH=$(libbacktrace) $(exe)
339 #run_exe = LD_LIBRARY_PATH=../libbacktrace/.libs $(exe)
340 endif
341 ifeq ($(uname),OpenBSD)
342 run_exe = MEMENTO_ABORT_ON_LEAK=1 MEMENTO_HIDE_MULTIPLE_REALLOCS=1 $(exe)
343 endif
344 endif
345
346 exe_tables = src/build/extract-tables-$(build).exe
347 exe-tables: $(exe_tables)
348 exe-tables-test: $(exe_tables)
349 $< test/agstat.pdf
350
351 ifeq (0,1)
352 # Do not commit changes to above line.
353 #
354 # Special rules for populating .ref directories with current output. Useful to
355 # initialise references outputs for new output type.
356 #
357 test/%.docx.dir.ref/: test/generated/%.docx.dir/
358 rsync -ai $< $@
359 test/%.odt.dir.ref/: test/generated/%.odt.dir/
360 rsync -ai $< $@
361 test/%.text.ref: test/generated/%.text
362 rsync -ai $< $@
363
364 _update_tables_leafs = $(patsubst test/%, %, $(test_tables_pdfs))
365 # Update all table docx reference outputs.
366 #
367 _update-docx-tables:
368 for i in $(_update_tables_leafs); do rsync -ai test/generated/$$i.mutool.docx.dir/ test/$$i.mutool.docx.dir.ref/; done
369 # Update all table odt reference outputs.
370 #
371 _update-odt-tables:
372 for i in $(_update_tables_leafs); do rsync -ai test/generated/$$i.mutool.odt.dir/ test/$$i.mutool.odt.dir.ref/; done
373 endif
374
375 # Rules that make the various intermediate targets required by $(tests).
376 #
377
378 %.extract.docx: % $(exe)
379 @echo
380 @echo == Generating docx with extract.exe
381 $(run_exe) -r 0 -i $< -f docx -o $@
382
383 %.extract.odt: % $(exe)
384 @echo
385 @echo == Generating odt with extract.exe
386 $(run_exe) -r 0 -i $< -f odt -o $@
387
388 %.extract-rotate.docx: % $(exe) Makefile
389 @echo
390 @echo == Generating docx with rotation with extract.exe
391 $(run_exe) -r 1 -s 0 -i $< -f docx -o $@
392
393 %.extract-rotate-spacing.docx: % $(exe) Makefile
394 @echo
395 @echo == Generating docx with rotation with extract.exe
396 $(run_exe) -r 1 -s 1 -i $< -f docx -o $@
397
398 %.extract-autosplit.docx: % $(exe)
399 @echo
400 @echo == Generating docx with autosplit with extract.exe
401 $(run_exe) -r 0 -i $< -f docx --autosplit 1 -o $@
402
403 %.extract-template.docx: % $(exe)
404 @echo
405 @echo == Generating docx using src/template.docx with extract.exe
406 $(run_exe) -r 0 -i $< -f docx -t src/template.docx -o $@
407
408 test/generated/%.dir.diff: test/generated/%.dir test/%.dir.ref
409 @echo
410 @echo == Checking $<
411 $(DIFF_OR_CP) $^
412 #if diff -ruq $^; then true; else echo "@@@ failure... fix with: rsync -ai" $^; false; fi
413
414 test/generated/%.html.diff: test/generated/%.html test/%.html.ref
415 @echo
416 @echo == Checking $<
417 $(DIFF_OR_CP) $^
418
419 # This checks that -t src/template.docx gives identical results.
420 #
421 test/generated/%.extract-template.docx.diff: test/generated/%.extract-template.docx.dir test/%.extract.docx.dir.ref
422 @echo
423 @echo == Checking $<
424 $(DIFF_OR_CP) $^
425
426 # Unzips .docx into .docx.dir/ directory, and prettyfies the .xml files.
427 %.docx.dir: %.docx .ALWAYS
428 @echo
429 @echo == Extracting .docx into directory.
430 @rm -r $@ 2>/dev/null || true
431 unzip -q -d $@ $<
432
433 # Unzips .odt into .odt.dir/ directory, and prettyfies the .xml files.
434 %.odt.dir: %.odt
435 @echo
436 @echo == Extracting .odt into directory.
437 @rm -r $@ 2>/dev/null || true
438 unzip -q -d $@ $<
439
440 %.xml.pretty.xml: %.xml
441 xmllint --format $< > $@
442
443 # Uses zip to create .docx file by zipping up a directory. Useful to recreate
444 # .docx from reference directory test/*.docx.dir.ref.
445 %.docx: %
446 @echo
447 @echo == Zipping directory into .docx file.
448 @rm -r $@ 2>/dev/null || true
449 cd $< && zip -r ../$(notdir $@) .
450
451 # Uses zip to create .odt file by zipping up a directory. Useful to recreate
452 # .docx from reference directory test/*.odt.dir.ref.
453 %.odt: %
454 @echo
455 @echo == Zipping directory into .odt file.
456 @rm -r $@ 2>/dev/null || true
457 cd $< && zip -r ../$(notdir $@) .
458
459 # Prettifies each .xml file within .docx.dir/ directory.
460 %.docx.dir.pretty: %.docx.dir/
461 @rm -r $@ $@- 2>/dev/null || true
462 cp -pr $< $@-
463 ./src/docx_template_build.py --pretty $@-
464 mv $@- $@
465
466 # Converts .pdf directly to .docx using mutool.
467 test/generated/%.pdf.mutool.docx: test/%.pdf $(mutool)
468 @echo
469 @echo == Converting .pdf directly to .docx using mutool.
470 @mkdir -p test/generated
471 $(mutool_run) convert -O mediabox-clip=yes -o $@ $<
472
473 test/generated/%.pdf.mutool-norotate.docx: test/%.pdf $(mutool)
474 @echo
475 @echo == Converting .pdf directly to .docx using mutool.
476 @mkdir -p test/generated
477 $(mutool_run) convert -O mediabox-clip=yes,rotation=no -o $@ $<
478
479 test/generated/%.pdf.mutool-spacing.docx: test/%.pdf $(mutool)
480 @echo
481 @echo == Converting .pdf directly to .docx using mutool.
482 @mkdir -p test/generated
483 $(mutool_run) convert -O mediabox-clip=yes,spacing=yes -o $@ $<
484
485 # Converts .pdf directly to .docx using gs.
486 test/generated/%.pdf.gs.docx: test/%.pdf $(gs)
487 @echo
488 @echo == Converting .pdf directly to .docx using gs.
489 @mkdir -p test/generated
490 $(gs) -sDEVICE=docxwrite -o $@ $<
491
492 # Converts .pdf directly to .odt using mutool.
493 test/generated/%.pdf.mutool.odt: test/%.pdf $(mutool)
494 @echo
495 @echo == Converting .pdf directly to .odt using mutool.
496 @mkdir -p test/generated
497 $(mutool_run) convert -O mediabox-clip=no -o $@ $<
498
499 # Converts .pdf directly to .html using mutool
500 test/generated/%.pdf.mutool.html: test/%.pdf $(mutool)
501 @echo
502 @echo == Converting .pdf directly to .html using mutool.
503 @mkdir -p test/generated
504 $(mutool_run) convert -F docx -O html -o $@ $<
505
506 # Converts .pdf directly to .text using mutool
507 test/generated/%.pdf.mutool.text: test/%.pdf $(mutool)
508 @echo
509 @echo == Converting .pdf directly to .text using mutool.
510 @mkdir -p test/generated
511 $(mutool_run) convert -F docx -O text -o $@ $<
512
513 # Valgrind test
514 #
515 #valgrind: $(exe) test/generated/Python2.pdf.intermediate-mu.xml
516 # valgrind --leak-check=full $(exe) -h -r 1 -s 0 -i test/generated/Python2.pdf.intermediate-mu.xml -o test/generated/valgrind-out.docx
517 # @echo $@: passed
518
519 # Memento tests.
520 #
521 ifeq ($(build),memento)
522 mutool_memento_extract = ../../build/memento/mutool
523 memento_failat_gdb := $(gdb) -ex 'b Memento_breakpoint' -ex r -ex c -ex bt --args
524
525 # Memento squeeze with test/text_graphic_image.pdf runs quickly - just 2,100 events taking 20s.
526 #
527 # test/Python2.pdf is much slower - 301,900 events, taking around 8h.
528 #
529 msqueeze-mutool-docx:
530 MEMENTO_SQUEEZEAT=1 ./src/memento.py -q 100 $(mutool_run) convert -o $@.docx test/text_graphic_image.pdf
531 msqueeze-mutool-docx-failat:
532 MEMENTO_FAILAT=1960 $(memento_failat_gdb) $(mutool) convert -o $@.docx test/text_graphic_image.pdf
533 msqueeze-mutool-odt:
534 MEMENTO_SQUEEZEAT=1 ./src/memento.py -q 100 $(mutool_run) convert -o $@.docx test/text_graphic_image.pdf
535 msqueeze-mutool-odt2:
536 MEMENTO_SQUEEZEAT=4000 ./src/memento.py -q 100 $(mutool_run) convert -o $@.docx test/Python2.pdf
537 msqueeze-mutool-table:
538 MEMENTO_SQUEEZEAT=1 ./src/memento.py -q 100 $(mutool_run) convert -F docx -O html -o $@.html test/agstat.pdf
539 msqueeze-mutool-table-docx:
540 MEMENTO_SQUEEZEAT=1 ./src/memento.py -q 100 $(mutool_run) convert -o $@.docx test/agstat.pdf
541 msqueeze-mutool-table-odt:
542 MEMENTO_SQUEEZEAT=1 ./src/memento.py -q 100 $(mutool_run) convert -o $@.odt test/agstat.pdf
543 msqueeze-mutool-table-failat:
544 MEMENTO_FAILAT=296643 MEMENTO_HIDE_MULTIPLE_REALLOCS=1 $(gdb) -ex 'b Memento_breakpoint' -ex r -ex c -ex bt --args $(mutool_memento_extract) convert -F docx -O html -o $@.html test/agstat.pdf
545 endif
546
547
548 # Temporary rules for generating reference files.
549 #
550 #test/%.xml.extract-rotate-spacing.docx.dir.ref: test/generated/%.xml.extract-rotate-spacing.docx.dir
551 # @echo
552 # @echo copying $< to %@
553 # rsync -ai $</ $@/
554
555
556 # Buffer unit test.
557 #
558 exe_buffer_test = src/build/buffer-test-$(build).exe
559 exe_buffer_test_src = src/buffer.c src/buffer-test.c src/outf.c src/alloc.c src/mem.c
560 ifeq ($(build),memento)
561 exe_buffer_test_src += src/memento.c
562 endif
563 exe_buffer_test_obj = $(patsubst src/%.c, src/build/%.c-$(build).o, $(exe_buffer_test_src))
564 exe_buffer_test_dep = $(exe_buffer_test_obj:.o=.d)
565 $(exe_buffer_test): $(exe_buffer_test_obj)
566 $(CC) $(flags_link) -o $@ $^
567 test-buffer: $(exe_buffer_test)
568 @echo
569 @echo == Running test-buffer
570 mkdir -p test/generated
571 ./$<
572 @echo $@: passed
573 test-buffer-valgrind: $(exe_buffer_test)
574 @echo
575 @echo == Running test-buffer with valgrind
576 mkdir -p test/generated
577 valgrind --leak-check=full ./$<
578 @echo $@: passed
579
580 ifeq ($(build),memento)
581 test-buffer-msqueeze: $(exe_buffer_test)
582 MEMENTO_SQUEEZEAT=1 ./src/memento.py -q 1 ./$<
583 endif
584
585 # Misc unit test.
586 #
587 exe_misc_test = src/build/misc-test-$(build).exe
588 exe_misc_test_src = \
589 src/alloc.c \
590 src/astring.c \
591 src/buffer.c \
592 src/mem.c \
593 src/misc-test.c \
594 src/outf.c \
595 src/xml.c \
596
597 ifeq ($(build),memento)
598 exe_misc_test_src += src/memento.c
599 endif
600 exe_misc_test_obj = $(patsubst src/%.c, src/build/%.c-$(build).o, $(exe_misc_test_src))
601 exe_misc_test_dep = $(exe_buffer_test_obj:.o=.d)
602 $(exe_misc_test): $(exe_misc_test_obj)
603 $(CC) $(flags_link) -o $@ $^
604 test-misc: $(exe_misc_test)
605 @echo
606 @echo == Running test-misc
607 ./$<
608 @echo $@: passed
609
610 # Source code check.
611 #
612 test-src:
613 @echo
614 @echo == Checking for use of ssize_t in source.
615 if grep -wn ssize_t src/*.c src/*.h include/*.h; then false; else true; fi
616 @echo == Checking for use of strdup in source.
617 if grep -wn strdup `ls -d src/*.c src/*.h|grep -v src/memento.` include; then false; else true; fi
618 @echo == Checking for use of bzero in source.
619 if grep -wn bzero src/*.c src/*.h include/*.h; then false; else true; fi
620 @echo Checking for variables defined inside for-loop '(...)'.
621 if egrep -wn 'for *[(] *[a-zA-Z0-9]+ [a-zA-Z0-9]' src/*.c src/*.h; then false; else true; fi
622 @echo $@: passed
623
624 # Check that all defined global symbols start with 'extract_'. This is not
625 # included in the overall 'test' target because the use of '!egrep ...' appears
626 # to break on some cluster machines.
627 #
628 test-obj:
629 @echo
630 nm -egPC $(exe_obj) | egrep '^[a-zA-Z0-9_]+ T' | grep -vw ^main | ! egrep -v ^extract_
631 @echo $@: passed
632
633 # Compile rule. We always include src/docx_template.c as a prerequisite in case
634 # code #includes docx_template.h. We use -std=gnu90 to catch 'ISO C90 forbids
635 # mixing declarations and code' errors while still supporting 'inline'.
636 #
637 src/build/%.c-$(build).o: src/%.c src/docx_template.c src/odt_template.c
638 @mkdir -p src/build
639 $(CC) -std=gnu90 -c $(flags_compile) -o $@ $<
640
641 src/build/%.cpp-$(build).o: src/%.cpp
642 @mkdir -p src/build
643 $(CXX) -c -Wall -W -I /usr/local/include/opencv4 -o $@ $<
644
645 # Rule for machine-generated source code, src/docx_template.c. Also generates
646 # src/docx_template.h.
647 #
648 # These files are also in git to allow builds if python is not available.
649 #
650 src/docx_template.c: src/docx_template_build.py .ALWAYS
651 @echo
652 @echo == Building $@
653 ./src/docx_template_build.py -i src/template.docx -n docx -o src/docx_template
654
655 src/odt_template.c: src/docx_template_build.py .ALWAYS
656 @echo
657 @echo == Building $@
658 ./src/docx_template_build.py -i src/template.odt -n odt -o src/odt_template
659
660 .ALWAYS:
661 .PHONY: .ALWAYS
662
663 # Tell make to preserve all intermediate files.
664 #
665 .SECONDARY:
666
667
668 # Rule for tags.
669 #
670 tags: .ALWAYS
671 ectags -R --extra=+fq --c-kinds=+px .
672
673
674 # Clean rule.
675 #
676 clean:
677 rm -r src/build test/generated src/template.docx.dir 2>/dev/null || true
678
679 # Cleans test/generated except for intermediate files, which are slow to create
680 # (when using gs).
681 clean2:
682 rm -r test/generated/*.pdf.mutool*.docx* 2>/dev/null || true
683 rm -r src/build 2>/dev/null || true
684 .PHONY: clean
685
686
687 # Include dynamic dependencies.
688 #
689 # We use $(sort ...) to remove duplicates
690 #
691 dep = $(sort $(exe_dep) $(exe_buffer_test_dep) $(exe_misc_test_dep) $(exe_ziptest_dep))
692
693 -include $(dep)