uwrap: Add support for getgroups_chk()
[uid_wrapper.git] / ConfigureChecks.cmake
1 include(CheckIncludeFile)
2 include(CheckSymbolExists)
3 include(CheckFunctionExists)
4 include(CheckLibraryExists)
5 include(CheckTypeSize)
6 include(CheckStructHasMember)
7 include(CheckPrototypeDefinition)
8 include(TestBigEndian)
9
10 set(PACKAGE ${PROJECT_NAME})
11 set(VERSION ${PROJECT_VERSION})
12
13 set(BINARYDIR ${uid_wrapper_BINARY_DIR})
14 set(SOURCEDIR ${uid_wrapper_SOURCE_DIR})
15
16 function(COMPILER_DUMPVERSION _OUTPUT_VERSION)
17     # Remove whitespaces from the argument.
18     # This is needed for CC="ccache gcc" cmake ..
19     string(REPLACE " " "" _C_COMPILER_ARG "${CMAKE_C_COMPILER_ARG1}")
20
21     execute_process(
22         COMMAND
23             ${CMAKE_C_COMPILER} ${_C_COMPILER_ARG} -dumpversion
24         OUTPUT_VARIABLE _COMPILER_VERSION
25     )
26
27     string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
28            _COMPILER_VERSION "${_COMPILER_VERSION}")
29
30     set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
31 endfunction()
32
33 if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
34     compiler_dumpversion(GNUCC_VERSION)
35     if (NOT GNUCC_VERSION EQUAL 34)
36         set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden")
37         check_c_source_compiles(
38 "void __attribute__((visibility(\"default\"))) test() {}
39 int main(void){ return 0; }
40 " WITH_VISIBILITY_HIDDEN)
41         set(CMAKE_REQUIRED_FLAGS "")
42     endif (NOT GNUCC_VERSION EQUAL 34)
43 endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
44
45 # HEADERS
46 check_include_file(sys/types.h HAVE_SYS_TYPES_H)
47 check_include_file(sys/syscall.h HAVE_SYS_SYSCALL_H)
48 check_include_file(syscall.h HAVE_SYSCALL_H)
49 check_include_file(grp.h HAVE_GRP_H)
50 check_include_file(unistd.h HAVE_UNISTD_H)
51
52 # FUNCTIONS
53 check_function_exists(strncpy HAVE_STRNCPY)
54 check_function_exists(vsnprintf HAVE_VSNPRINTF)
55 check_function_exists(snprintf HAVE_SNPRINTF)
56
57 check_function_exists(seteuid HAVE_SETEUID)
58 check_function_exists(setreuid HAVE_SETREUID)
59 check_function_exists(setresuid HAVE_SETRESUID)
60 check_function_exists(getresuid HAVE_GETRESUID)
61 check_function_exists(getresgid HAVE_GETRESGID)
62
63 check_function_exists(setegid HAVE_SETEGID)
64 check_function_exists(setregid HAVE_SETREGID)
65 check_function_exists(setresgid HAVE_SETRESGID)
66
67 check_function_exists(getgroups HAVE_GETGROUPS)
68 check_function_exists(__getgroups_chk HAVE___GETGROUPS_CHK)
69 check_function_exists(setgroups HAVE_SETGROUPS)
70
71 if (HAVE_SETGROUPS)
72     check_prototype_definition(setgroups
73         "int setgroups(int size, const gid_t *list)"
74         "-1"
75         "unistd.h"
76         HAVE_SETGROUPS_INT)
77 endif (HAVE_SETGROUPS)
78
79 check_function_exists(syscall HAVE_SYSCALL)
80
81 if (HAVE_SYSCALL)
82     set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
83
84     check_prototype_definition(syscall
85         "int syscall(int sysno, ...)"
86         "-1"
87         "unistd.h;sys/syscall.h"
88         HAVE_SYSCALL_INT)
89     set(CMAKE_REQUIRED_DEFINITIONS)
90 endif (HAVE_SYSCALL)
91
92 # OPTIONS
93
94 if (LINUX)
95     if (HAVE_SYS_SYSCALL_H)
96        list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DHAVE_SYS_SYSCALL_H")
97     endif (HAVE_SYS_SYSCALL_H)
98     if (HAVE_SYSCALL_H)
99         list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DHAVE_SYSCALL_H")
100     endif (HAVE_SYSCALL_H)
101
102 check_c_source_compiles("
103 #include <sys/types.h>
104 #ifdef HAVE_SYS_SYSCALL_H
105 #include <sys/syscall.h>
106 #endif
107 #ifdef HAVE_SYSCALL_H
108 #include <syscall.h>
109 #endif
110 #include <unistd.h>
111
112 int main(void) {
113     syscall(SYS_setresuid32, -1, -1, -1);
114     syscall(SYS_setresgid32, -1, -1, -1);
115     syscall(SYS_setreuid32, -1, -1);
116     syscall(SYS_setregid32, -1, -1);
117     syscall(SYS_setuid32, -1);
118     syscall(SYS_setgid32, -1);
119     syscall(SYS_setgroups32, 0, NULL);
120
121     return 0;
122 }" HAVE_LINUX_32BIT_SYSCALLS)
123
124     set(CMAKE_REQUIRED_DEFINITIONS)
125 endif (LINUX)
126
127 check_c_source_compiles("
128 #include <stdbool.h>
129 int main(void) {
130     bool x;
131     bool *p_x = &x;
132     __atomic_load(p_x, &x, __ATOMIC_RELAXED);
133     return 0;
134 }" HAVE_GCC_ATOMIC_BUILTINS)
135
136 check_c_source_compiles("
137 __thread int tls;
138
139 int main(void) {
140     return 0;
141 }" HAVE_GCC_THREAD_LOCAL_STORAGE)
142
143 check_c_source_compiles("
144 void test_constructor_attribute(void) __attribute__ ((constructor));
145
146 void test_constructor_attribute(void)
147 {
148      return;
149 }
150
151 int main(void) {
152      return 0;
153 }" HAVE_CONSTRUCTOR_ATTRIBUTE)
154
155 check_c_source_compiles("
156 void test_destructor_attribute(void) __attribute__ ((destructor));
157
158 void test_destructor_attribute(void)
159 {
160     return;
161 }
162
163 int main(void) {
164     return 0;
165 }" HAVE_DESTRUCTOR_ATTRIBUTE)
166
167 check_c_source_compiles("
168 #pragma init (test_constructor)
169 void test_constructor(void);
170
171 void test_constructor(void)
172 {
173      return;
174 }
175
176 int main(void) {
177      return 0;
178 }" HAVE_PRAGMA_INIT)
179
180 check_c_source_compiles("
181 #pragma fini (test_destructor)
182 void test_destructor(void);
183
184 void test_destructor(void)
185 {
186     return;
187 }
188
189 int main(void) {
190     return 0;
191 }" HAVE_PRAGMA_FINI)
192
193 # If this produces a warning treat it as error!
194 set(CMAKE_REQUIRED_FLAGS "-Werror")
195 check_c_source_compiles("
196 void test_address_sanitizer_attribute(void) __attribute__((no_sanitize_address));
197
198 void test_address_sanitizer_attribute(void)
199 {
200     return;
201 }
202
203 int main(void) {
204     return 0;
205 }" HAVE_ADDRESS_SANITIZER_ATTRIBUTE)
206 set(CMAKE_REQUIRED_FLAGS)
207
208 check_c_source_compiles("
209 void log_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
210
211 int main(void) {
212     return 0;
213 }" HAVE_FUNCTION_ATTRIBUTE_FORMAT)
214
215 check_c_source_compiles("
216 #define FALL_THROUGH __attribute__((fallthrough))
217
218 enum direction_e {
219     UP = 0,
220     DOWN,
221 };
222
223 int main(void) {
224     enum direction_e key = UP;
225     int i = 10;
226     int j = 0;
227
228     switch (key) {
229     case UP:
230         i = 5;
231         FALL_THROUGH;
232     case DOWN:
233         j = i * 2;
234         break;
235     default:
236         break;
237     }
238
239     return 0;
240 }" HAVE_FALLTHROUGH_ATTRIBUTE)
241
242 # SYSTEM LIBRARIES
243
244 find_library(DLFCN_LIBRARY dl)
245 if (DLFCN_LIBRARY)
246     list(APPEND _REQUIRED_LIBRARIES ${DLFCN_LIBRARY})
247 else()
248     check_function_exists(dlopen HAVE_DLOPEN)
249     if (NOT HAVE_DLOPEN)
250         message(FATAL_ERROR "FATAL: No dlopen() function detected")
251     endif()
252 endif()
253
254 if (OSX)
255     set(HAVE_APPLE 1)
256 endif (OSX)
257
258 # ENDIAN
259 if (NOT WIN32)
260     test_big_endian(WORDS_BIGENDIAN)
261 endif (NOT WIN32)
262
263 set(UIDWRAP_REQUIRED_LIBRARIES ${_REQUIRED_LIBRARIES} CACHE INTERNAL "uidwrap required system libraries")