1# vim:se syn=tcl:
2#
3
4use cc cc-lib cc-shared pkg-config
5
6set maj_ver 1
7set med_ver 17
8set min_ver 5
9set dev_ver 0
10define PKG_API [expr $maj_ver * 1000000 + $med_ver * 1000 + $min_ver]
11define VERSION $maj_ver.$med_ver.$min_ver[expr {$dev_ver ? ".$dev_ver" : ""}]
12
13# Add any user options here
14options {
15	pkgconfigdir:WHERE => "path to the directory where to install pc files"
16	with-ldns => "add support for libldns"
17	with-libarchive.pc => "build with libarchive getting flags via pc files"
18	with-coverage => "build with llvm coverage support"
19	with-asan => "build with libasan support"
20	with-ubsan => "Build with libubsan support"
21	default-format:txz => "Default compression format: tzst, txz (default), tbz, tar"
22}
23
24if {[opt-str pkgconfigdir dir]} {
25	define pkgconfigdir $dir
26} else {
27	if {[string match *-freebsd* [get-define host]]} {
28		define pkgconfigdir [get-define prefix]/libdata/pkgconfig
29	} else {
30		define pkgconfigdir [get-define prefix]/lib/pkgconfig
31	}
32}
33
34# default compression format
35
36if {[opt-str default-format fmt]} {
37	switch $fmt \
38	    "tzst" { set comp TZS } \
39	    "txz" { set comp TXZ } \
40	    "tbz" { set comp TBZ } \
41	    "tgz" { set comp TGZ } \
42	    "tar" { set comp TAR } \
43	    "default" { user-error "Invalid format $fmt" }
44	define DEFAULT_COMPRESSION $comp
45} else {
46	define DEFAULT_COMPRESSION TXZ
47}
48
49cc-check-tools ar ranlib strip
50
51define EXTRA_LIBS ""
52define LIBVERSION 4
53define LIBSOEXT [format [get-define SH_SOEXTVER] [get-define LIBVERSION]]
54
55define GITHASH ""
56if {[cc-check-progs git] && [file exists .git] &&
57    ![catch {exec git rev-parse --short HEAD} gitrev] &&
58    ![catch {exec git diff-index -m --name-only HEAD} gitdirty]} {
59	define GITHASH -$gitrev[expr {$gitdirty eq {} ? {} : {-dirty}}]
60}
61
62if {[string match *-linux* [get-define host]]} {
63	cc-with { -libs { -lbsd }} {
64		if {[cc-check-functions getprogname]} {
65			define-append EXTRA_LIBS -lbsd
66			define-feature libbsd
67		} else {
68			user-error "Unable to find libbsd"
69		}
70	}
71} else {
72	define-feature static
73}
74
75if {![opt-bool with-libarchive.pc]} {
76	cc-with { -libs { -larchive }} {
77		if {![cc-check-functions archive_read_open]} {
78			user-error "Unable to find libarchive"
79		}
80	}
81}
82
83cc-with { -libs { -lz }} {
84	if {![cc-check-functions zlibVersion]} {
85		user-error "Unable to find zlib"
86	}
87}
88
89cc-with { -libs { -lbz2 }} {
90	if {![cc-check-functions BZ2_bzReadOpen]} {
91		user-error "Unable to find bzip2"
92	}
93}
94
95cc-with { -libs { -llzma }} {
96	if {![cc-check-functions lzma_version_string]} {
97		user-error "Unable to find liblzma"
98	}
99}
100if {[string match *-freebsd* [get-define host]]} {
101	cc-with { -libs { -lmd }} {
102		if {![cc-check-functions SHA256_Data]} {
103			user-error "Unable to find libmd"
104		} else {
105			define-feature libmd
106		}
107	}
108}
109
110cc-with { -libs { -larchive }} {
111	cc-check-functions archive_write_add_filter_zstd
112}
113
114define ZSTDLIB ""
115cc-with { -libs { -lprivate_zstd }} {
116	if {[cc-check-functions ZSTD_versionNumber]} {
117		define ZSTDLIB "-lprivate_zstd"
118	}
119}
120
121# Atomics
122msg-checking "Checking for atomic builtins... "
123if {[cctest -code {
124	volatile unsigned long val = 1;
125	__sync_synchronize();
126	__sync_val_compare_and_swap(&val, 1, 0);
127	__sync_add_and_fetch(&val, 1);
128	__sync_sub_and_fetch(&val, 1);
129	return 0;
130	}
131]} {
132	msg-result ok
133	define-feature atomic_builtins
134} else {
135	msg-result no
136	define-feature atomic_builtins 0
137}
138
139msg-checking "Checking for /proc/self/fd support... "
140if {[file exists /proc/self/fd]} {
141	msg-result ok
142	define-feature proc-pid
143} else {
144	msg-result no
145	define-feature proc-pid 0
146}
147
148foreach fct [list memmove usleep pread pwrite] {
149	if {![cc-check-functions $fct]} {
150		user-error "Cannot find $fct"
151	}
152}
153
154cc-with { -includes fcntl.h } {
155	cc-check-decls F_CLOSEM
156}
157
158cc-with { -includes sys/socket.h } {
159	cc-check-decls SOCK_SEQPACKET
160}
161
162cc-with { -includes netinet/in.h } {
163	cc-check-members "struct sockaddr_in.sin_len"
164}
165
166cc-with { -includes sys/stat.h } {
167	cc-check-members "struct stat.st_mtim" "struct stat.st_flags"
168}
169
170# check for sqlite
171cc-check-functions gmtime_r isnan localtime_r strchrnul strerror_r fdatasync \
172	fchown lstat readlink
173cc-check-includes stdint.h inttypes.h
174
175# check for pkg itself
176cc-check-functions arc4random arc4random_stir basename_r chflagsat \
177	closefrom dirfd eaccess fopencookie fstatfs funopen getprogname strnstr \
178	strtofflags strtonum sysconf utimensat __res_setservers unlinkat \
179	faccessat fstatat openat readlinkat fflagstostr reallocarray strchrnul
180
181cc-with { -includes { libutil.h }} {
182	if {[cc-check-decls humanize_number]} {
183	}
184}
185
186if {![cc-check-functions fts_open]} {
187	cc-with { -libs { -lfts }} {
188		if {[cc-check-functions fts_open]} {
189			define-feature LIBFTS
190		}
191	}
192}
193
194if {[get-define HAVE_DECL_HUMANIZE_NUMBER] eq 1} {
195	cc-with { -libs { -lutil }} {
196		if {[cc-check-functions humanize_number]} {
197			define-feature LIBUTIL
198		}
199	}
200}
201
202if {![cc-check-functions dlclose]} {
203	cc-with { -libs { -ldl }} {
204		if {[cc-check-functions dlclose]} {
205			define-feature LIBDL
206		}
207	}
208}
209
210if {![cc-check-functions __res_query]} {
211	cc-with { -libs { -lresolv }} {
212		if {[cc-check-functions __res_query]} {
213			define-feature LIBRESOLV
214		}
215	}
216}
217
218cc-check-includes link.h machine/endian.h osreldate.h readpassphrase.h \
219	sys/procctl.h sys/statfs.h sys/statvfs.h libutil.h
220
221# for compat
222cc-check-includes dirent.h
223
224#endian stuff
225foreach header [list endian.h sys/endian.h] {
226	if {[cc-check-includes $header]} {
227		cc-with [list -includes $header] {
228			cc-check-decls be16dec be16enc be32dec be32enc be64dec be64enc \
229				le16dec le16enc le32dec le32enc le64dec le64enc
230		}
231	}
232}
233
234if {[string match *-darwin* [get-define host]]} {
235	define libmachista
236	define waflags ""
237	define nowaflags ""
238} else {
239# libelf
240	define waflags "-Wl,-whole-archive"
241	define nowaflags "-Wl,-no-whole-archive"
242	cc-with { -includes { sys/types.h }} {
243		cc-check-includes elf-hints.h sys/elf_common.h
244	}
245
246	if {[cc-check-includes gelf.h libelf.h]} {
247		cc-with { -libs { -lelf } } {
248			if {[cc-check-functions gelf_getehdr]} {
249				define-feature libelf
250				define libelf-external
251				define-append EXTRA_LIBS -lelf
252				cc-check-types Elf_Note
253			} else {
254				define libelf-internal
255				define-feature libelf 0
256			}
257		}
258	} else {
259		define-feature libelf 0
260		define libelf-internal
261	}
262}
263
264cc-with { -libs { -ljail} } {
265	if {[cc-check-functions jail_getid]} {
266		define-feature libjail
267		define-append EXTRA_LIBS -ljail
268	}
269}
270
271# libbsd
272cc-check-includes bsd/err.h bsd/libutil.h bsd/readpassphrase.h \
273	bsd/stdio.h bsd/stdlib.h bsd/strlib.h bsd/string.h \
274	bsd/sys/cdefs.h bsd/unistd.h
275
276if {[opt-bool with-asan]} {
277	define-append ASAN_CFLAGS -O0 -ggdb -fsanitize=address
278	define-append ASAN_LDFLAGS -fsanitize=address
279	if {[string match *-linux* [get-define host]]} {
280		# ASAN depends on libdl for dlsym when building with GCC
281		define-append ASAN_LDFLAGS -ldl
282	}
283	define asan 1
284	undefine HAVE_STATIC
285}
286if {[opt-bool with-ubsan]} {
287	# Avoid alignment error when building with UBSan inside _mum_hash_avx2
288	define-append UBSAN_CFLAGS -D_MUM_UNALIGNED_ACCESS=0
289	define-append UBSAN_CFLAGS -O0 -ggdb -fsanitize=undefined
290	define-append UBSAN_LDFLAGS -fsanitize=undefined
291	define ubsan 1
292}
293if {[opt-bool with-coverage]} {
294	define-append COVERAGE_CFLAGS -O0 -ggdb -fprofile-instr-generate -fcoverage-mapping
295	define-append COVERAGE_LDFLAGS -fprofile-instr-generate -fuse-ld=/usr/local/bin/ld.lld
296	define CC /usr/local/bin/clang
297	define CC_FOR_BUILD /usr/local/bin/clang
298	define coverage 1
299# disable capsicum when coverage is used because coverage does not work in
300# capsicum mode
301} else {
302# capsicum
303	if {[cc-check-functions cap_sandboxed]} {
304		define-feature capsicum
305			cc-check-includes sys/capsicum.h
306	}
307}
308
309if {[pkg-config-init 0]} {
310# atf
311	if {[pkg-config atf-c] && [cc-check-progs kyua]} {
312		define TESTS
313		puts "test suite will be built"
314	} else {
315		puts "Skipping test suite"
316	}
317	if {[opt-bool with-ldns]} {
318		if {![pkg-config libldns]} {
319			user-error "Unable to find libldns"
320		} else {
321			define PKG_LIBDNS_LIBS_STATIC [exec pkg-config --static --libs-only-l libldns]
322		}
323	}
324	if {[opt-bool with-libarchive.pc]} {
325		if {![pkg-config libarchive]} {
326			user-error "Unable to find libarchive"
327		} else {
328			define PKG_LIBARCHIVE_LIBS_STATIC [exec pkg-config --static --libs-only-l libarchive]
329			cc-with { -libs { -larchive }} {
330				cc-check-functions archive_write_add_filter_zstd
331			}
332		}
333	}
334}
335
336foreach repo [list binary] {
337	define-append REPOS $repo
338	define-append REPOS_LDFLAGS -L\$(top_builddir)/libpkg/repo/${repo} -lrepo-${repo}_pic
339	define-append REPOS_STATIC_LIBS \$(top_builddir)/libpkg/repo/${repo}/librepo-${repo}.a
340}
341
342# ccache
343if {[get-define CCACHE] ne {none}} {
344  define CC "[get-define CCACHE] [get-define CC]"
345}
346
347make-config-header pkg_config.h -bare { DEFAULT_* }
348make-config-header external/sqlite/config.h
349make-template mk/defs.mk.in
350make-template libpkg/pkg.h.in
351make-template libpkg/pkg.pc.in
352make-template tests/frontend/test_environment.sh.in
353make-template Makefile.autosetup Makefile
354
355foreach dir [list external/blake2 external/picosat \
356	external/linenoise external/libfetch external/sqlite \
357	external compat libpkg libpkg/repo libpkg/repo/binary src \
358	external/libucl external/libelf external/libmachista tests docs \
359	external/liblua external/msgpuck external/yxml scripts] {
360	make-template $dir/Makefile.autosetup $dir/Makefile
361}
362
363