summary refs log tree commit diff
path: root/CMakeLists.txt
blob: 1dcdc182bbcbb5a97528f14ff1532e20ff0fd396 (plain) (blame)
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
cmake_minimum_required(VERSION 3.10)

project(dash VERSION 0.5.11.5 LANGUAGES C)

include(CheckCSourceCompiles)
include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckStructHasMember)
include(CheckSymbolExists)
include(CheckTypeSize)
include(FindPkgConfig)
include(GNUInstallDirs)

check_c_source_compiles([[
void t() {}
void a() __attribute__((__alias__("t")));
int main() { a(); return 0; }
]] HAVE_ALIAS_ATTRIBUTE)

option(ENABLE_FNMATCH "Use fnmatch(3) from libc")
option(ENABLE_GLOB "Use glob(3) from libc")

# Checks for header files.
check_include_file("alloca.h" HAVE_ALLOCA_H)
check_include_file("paths.h" HAVE_PATHS_H)

# Check for declarations
check_symbol_exists(_PATH_BSHELL "paths.h" HAVE__PATH_BSHELL)
check_symbol_exists(_PATH_DEVNULL "paths.h" HAVE__PATH_DEVNULL)
check_symbol_exists(_PATH_TTY "paths.h" HAVE__PATH_TTY)
add_compile_definitions(
	$<$<NOT:$<BOOL:${HAVE__PATH_BSHELL}>>:_PATH_BSHELL="/bin/sh">
	$<$<NOT:$<BOOL:${HAVE__PATH_DEVNULL}>>:_PATH_DEVNULL="/dev/null">
	$<$<NOT:$<BOOL:${HAVE__PATH_TTY}>>:_PATH_TTY="/dev/tty">
)

# Some systems lack isblank
check_symbol_exists(isblank "ctype.h" HAVE_DECL_ISBLANK)

# Check for sizes of types
check_type_size("intmax_t" SIZEOF_INTMAX_T)
check_type_size("long long int" SIZEOF_LONG_LONG_INT)

# Select a fallback format string for intmax_t in case we don't find PRIdMAX
set(
	INTMAX_FSTR
	$<IF:$<EQUAL:${SIZEOF_INTMAX_T},${SIZEOF_LONG_LONG_INT}>,lld,jd>
)

# Check for PRIdMAX and define it to a fallback if not found
check_symbol_exists(PRIdMAX "inttypes.h" HAVE_PRIdMAX)
if(NOT HAVE_PRIdMAX)
	add_compile_definitions(PRIdMAX="${INTMAX_FSTR}")
endif()

# Checks for library functions.
check_symbol_exists(bsearch "stdlib.h" HAVE_BSEARCH)
check_symbol_exists(faccessat "unistd.h" HAVE_FACCESSAT)
check_symbol_exists(getpwnam "pwd.h" HAVE_GETPWNAM)
check_symbol_exists(getrlimit "sys/resource.h" HAVE_GETRLIMIT)
check_symbol_exists(isalpha "ctype.h" HAVE_ISALPHA)
check_symbol_exists(killpg "signal.h" HAVE_KILLPG)
check_symbol_exists(memcpy "string.h" HAVE_MEMCPY)
check_symbol_exists(sigsetmask "signal.h" HAVE_SIGSETMASK)
check_symbol_exists(stpcpy "string.h" HAVE_STPCPY)
check_symbol_exists(strchrnul "string.h" HAVE_STRCHRNUL)
check_symbol_exists(strsignal "string.h" HAVE_STRSIGNAL)
check_symbol_exists(strtod "stdlib.h" HAVE_STRTOD)
check_symbol_exists(strtoimax "inttypes.h" HAVE_STRTOIMAX)
check_symbol_exists(strtoumax "inttypes.h" HAVE_STRTOUMAX)
check_symbol_exists(sysconf "unistd.h" HAVE_SYSCONF)

# Check whether it's worth working around FreeBSD PR kern/125009.
# The traditional behavior of access/faccessat is crazy, but
# POSIX.1-2008 explicitly allows those functions to misbehave.
#
# Unaffected kernels:
#
# - all versions of Linux
# - NetBSD sys/kern/vfs_subr.c 1.64, 1997-04-23
# - FreeBSD 9 (r212002), 2010-09-10
# - OpenBSD sys/kern/vfs_subr.c 1.166, 2008-06-09
#
# Also worked around in Debian's libc0.1 2.13-19 when using
# kFreeBSD 8.
option(
	ENABLE_TEST_WORKAROUND
	"Guard against faccessat(2) that tells root all files are executable"
	AUTO
)
if(ENABLE_TEST_WORKAROUND STREQUAL "AUTO" AND HAVE_FACCESSAT)
	if(
		CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
		CMAKE_SYSTEM_NAME STREQUAL "GNU/kFreeBSD"
	)
		set(ENABLE_TEST_WORKAROUND ON)
	endif()
	set(
		HAVE_TRADITIONAL_FACCESSAT ON CACHE
		BOOL "Define if your faccessat tells root all files are executable"
	)
endif()

if(ENABLE_FNMATCH)
	check_symbol_exists(fnmatch "fnmatch.h" HAVE_FNMATCH)
endif()

if(HAVE_FNMATCH AND ENABLE_GLOB)
	check_symbol_exists(glob "glob.h" HAVE_GLOB)
endif()

# Check for klibc signal.
check_symbol_exists(bsd_signal "signal.h" HAVE_BSD_SIGNAL)
if(HAVE_BSD_SIGNAL)
	add_compile_definitions(signal=bsd_signal)
endif()

# Check if struct stat has st_mtim.
check_struct_has_member(
	"struct stat" "st_mtim.tv_sec" "sys/stat.h" HAVE_ST_MTIM
)

option(WITH_LIBEDIT "Compile with libedit support")
if(WITH_LIBEDIT)
	pkg_check_modules(LIBEDIT IMPORTED_TARGET libedit)
	if(LIBEDIT_FOUND)
		link_libraries(PkgConfig::LIBEDIT)
	else()
		unset(LIBEDIT_FOUND CACHE)
		check_include_file("histedit.h" HAVE_HISTEDIT_H)
		check_library_exists(edit history_init /usr/lib LIBEDIT_FOUND)
		if(HAVE_HISTEDIT_H AND LIBEDIT_FOUND)
			link_libraries(edit)
		else()
			message(SEND_ERROR "Can't find libedit.")
		endif()
		set(CMAKE_REQUIRED_LIBRARIES edit)
		check_symbol_exists(
			_el_fn_sh_complete "histedit.h" HAVE__EL_FN_SH_COMPLETE
		)
	endif()
else()
	add_compile_definitions(SMALL)
endif()

option(WITH_LINENO "Enable LINENO support" ON)

configure_file(config.h.in config.h)

add_subdirectory(src)