1AC_PREREQ([2.65])
2AC_INIT([libsodium],[1.0.18],
3  [https://github.com/jedisct1/libsodium/issues],
4  [libsodium],
5  [https://github.com/jedisct1/libsodium])
6AC_CONFIG_AUX_DIR([build-aux])
7AC_CONFIG_MACRO_DIR([m4])
8AC_CONFIG_SRCDIR([src/libsodium/sodium/version.c])
9AC_CANONICAL_HOST
10AM_INIT_AUTOMAKE([1.11 dist-bzip2 tar-ustar foreign subdir-objects])
11m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
12AM_MAINTAINER_MODE
13AM_DEP_TRACK
14
15AC_SUBST(VERSION)
16
17SODIUM_LIBRARY_VERSION_MAJOR=10
18SODIUM_LIBRARY_VERSION_MINOR=3
19DLL_VERSION=24
20SODIUM_LIBRARY_VERSION=26:0:3
21#                       | | |
22#                +------+ | +---+
23#                |        |     |
24#             current:revision:age
25#                |        |     |
26#                |        |     +- increment if interfaces have been added
27#                |        |        set to zero if interfaces have been removed
28#                |        |        or changed
29#                |        +- increment if source code has changed
30#                |           set to zero if current is incremented
31#                +- increment if interfaces have been added, removed or changed
32AC_SUBST(SODIUM_LIBRARY_VERSION_MAJOR)
33AC_SUBST(SODIUM_LIBRARY_VERSION_MINOR)
34AC_SUBST(SODIUM_LIBRARY_VERSION)
35AC_SUBST(DLL_VERSION)
36
37AC_LANG_ASSERT(C)
38LX_CFLAGS=${CFLAGS-NONE}
39PKGCONFIG_LIBS_PRIVATE=""
40
41dnl Path check
42
43AS_IF([pwd | fgrep ' ' > /dev/null 2>&1],
44  [AC_MSG_ERROR([The build directory contains whitespaces - This can cause tests/installation to fail due to limitations of some libtool versions])]
45)
46
47dnl Switches
48
49AC_ARG_ENABLE(ssp,
50[AS_HELP_STRING(--disable-ssp,Do not compile with -fstack-protector)],
51[
52  AS_IF([test "x$enableval" = "xno"], [
53    enable_ssp="no"
54  ], [
55    enable_ssp="yes"
56  ])
57],
58[
59  enable_ssp="yes"
60])
61
62AC_ARG_ENABLE(asm,
63[AS_HELP_STRING(--disable-asm,[Do not compile assembly code -- As a side effect, this disables CPU-specific implementations on non-Windows platforms. Only for use with targets such as WebAssembly.])],
64[
65  AS_IF([test "x$enableval" = "xno"], [
66    enable_asm="no"
67  ], [
68    enable_asm="yes"
69  ])
70],
71[
72  enable_asm="yes"
73])
74
75AS_IF([test "x$EMSCRIPTEN" != "x"], [
76  AX_CHECK_COMPILE_FLAG([-s ASSERTIONS=0], [
77    enable_asm="no"
78    AC_MSG_WARN([compiling to JavaScript - asm implementations disabled])
79  ], [
80    AC_MSG_WARN([EMSCRIPTEN environment variable defined, but emcc doesn't appear to be used - Assuming compilation to native code])
81    CFLAGS="$CFLAGS -U__EMSCRIPTEN__"
82    unset EMSCRIPTEN
83  ])
84])
85
86AC_ARG_ENABLE(pie,
87[AS_HELP_STRING(--disable-pie,Do not produce position independent executables)],
88 enable_pie=$enableval, enable_pie="maybe")
89
90AS_CASE([$host_os], [mingw*|cygwin*|msys], [enable_pie="no"])
91
92AC_ARG_ENABLE(blocking-random,
93[AS_HELP_STRING(--enable-blocking-random,Enable this switch only if /dev/urandom is totally broken on the target platform)],
94[
95  AS_IF([test "x$enableval" = "xyes"], [
96    AC_DEFINE([USE_BLOCKING_RANDOM], [1], [/dev/urandom is insecure on the target platform])
97  ])
98])
99
100AC_ARG_ENABLE(minimal,
101[AS_HELP_STRING(--enable-minimal,
102  [Only compile the minimum set of functions required for the high-level API])],
103[
104  AS_IF([test "x$enableval" = "xyes"], [
105    enable_minimal="yes"
106    SODIUM_LIBRARY_MINIMAL_DEF="#define SODIUM_LIBRARY_MINIMAL 1"
107    AC_DEFINE([MINIMAL], [1], [Define for a minimal build, without deprecated functions and functions that high-level APIs depend on])
108  ], [
109    enable_minimal="no"
110  ])
111],
112[
113  enable_minimal="no"
114])
115AM_CONDITIONAL([MINIMAL], [test x$enable_minimal = xyes])
116AC_SUBST(SODIUM_LIBRARY_MINIMAL_DEF)
117
118AC_ARG_WITH(pthreads, AC_HELP_STRING([--with-pthreads],
119 [use pthreads library, or --without-pthreads to disable threading support.]),
120 [ ], [withval="yes"])
121
122AS_IF([test "x$withval" = "xyes"], [
123  AX_PTHREAD([
124    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
125        #include <pthread.h>
126      ]], [[
127        pthread_mutex_t mutex;
128
129        pthread_mutex_lock(&mutex);
130        pthread_mutex_unlock(&mutex)
131      ]]
132    )], [
133        AC_DEFINE([HAVE_PTHREAD], [1], [Define if you have POSIX threads libraries and header files])
134        with_threads="yes"
135        LIBS="$PTHREAD_LIBS $LIBS"
136        PKGCONFIG_LIBS_PRIVATE="$PTHREAD_LIBS $PTHREAD_CFLAGS $PKGCONFIG_LIBS_PRIVATE"
137        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
138        CC="$PTHREAD_CC"
139      ])
140    ],
141    [ AC_MSG_NOTICE(pthread mutexes are not available) ]
142  )
143], [with_threads="no"])
144
145AC_ARG_WITH(safecode,
146[AS_HELP_STRING(--with-safecode,For maintainers only - please do not use)],
147[AS_IF([test "x$withval" = "xyes"], [
148    AC_ARG_VAR([SAFECODE_HOME], [set to the safecode base directory])
149    : ${SAFECODE_HOME:=/opt/safecode}
150    LDFLAGS="$LDFLAGS -L${SAFECODE_HOME}/lib"
151    LIBS="$LIBS -lsc_dbg_rt -lpoolalloc_bitmap -lstdc++"
152    CFLAGS="$CFLAGS -fmemsafety"
153  ])
154])
155
156AC_ARG_WITH(ctgrind,
157[AS_HELP_STRING(--with-ctgrind,For maintainers only - please do not use)],
158[AS_IF([test "x$withval" = "xyes"], [
159    AC_CHECK_LIB(ctgrind, ct_poison)
160  ])
161])
162
163AC_ARG_ENABLE(retpoline,
164[AS_HELP_STRING(--enable-retpoline,Use return trampolines for indirect calls)],
165[AS_IF([test "x$enableval" = "xyes"], [
166  AX_CHECK_COMPILE_FLAG([-mindirect-branch=thunk-inline],
167    [CFLAGS="$CFLAGS -mindirect-branch=thunk-inline"],
168    [AX_CHECK_COMPILE_FLAG([-mretpoline], [CFLAGS="$CFLAGS -mretpoline"])]
169  )
170  AX_CHECK_COMPILE_FLAG([-mindirect-branch-register])
171  ])
172])
173
174ENABLE_CWFLAGS=no
175AC_ARG_ENABLE(debug,
176[AS_HELP_STRING(--enable-debug,For maintainers only - please do not use)],
177[
178  AS_IF([test "x$enableval" = "xyes"], [
179    AS_IF([test "x$LX_CFLAGS" = "xNONE"], [
180      nxflags=""
181      for flag in `echo $CFLAGS`; do
182        AS_CASE([$flag],
183          [-O*], [ ],
184          [-g*], [ ],
185          [*], [AS_VAR_APPEND([nxflags], [" $flag"])])
186      done
187      CFLAGS="$nxflags -O -g3"
188    ])
189    ENABLE_CWFLAGS=yes
190    CPPFLAGS="$CPPFLAGS -DDEBUG=1 -U_FORTIFY_SOURCE"
191  ])
192])
193
194AC_ARG_ENABLE(opt,
195[AS_HELP_STRING(--enable-opt,Optimize for the native CPU - The resulting library will be faster but not portable)],
196[
197  AS_IF([test "x$enableval" = "xyes"], [
198    AX_CHECK_COMPILE_FLAG([-Ofast], [CFLAGS="$CFLAGS -Ofast"])
199    AX_CHECK_COMPILE_FLAG([-ftree-vectorize], [CFLAGS="$CFLAGS -ftree-vectorize"])
200    AX_CHECK_COMPILE_FLAG([-ftree-slp-vectorize], [CFLAGS="$CFLAGS -ftree-slp-vectorize"])
201    AX_CHECK_COMPILE_FLAG([-fomit-frame-pointer], [CFLAGS="$CFLAGS -fomit-frame-pointer"])
202    AX_CHECK_COMPILE_FLAG([-march=native], [CFLAGS="$CFLAGS -march=native"])
203  ])
204])
205
206AC_SUBST(MAINT)
207AC_SUBST(PKGCONFIG_LIBS_PRIVATE)
208
209AX_VALGRIND_CHECK
210
211dnl Checks
212
213AC_PROG_CC_C99
214AM_PROG_AS
215AC_USE_SYSTEM_EXTENSIONS
216AC_C_VARARRAYS
217
218AC_CHECK_DEFINE([__wasi__], [WASI="yes"], [])
219
220AC_CHECK_DEFINE([_FORTIFY_SOURCE], [], [
221  AX_CHECK_COMPILE_FLAG([-D_FORTIFY_SOURCE=2],
222    [CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"])
223])
224
225AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],
226  [CFLAGS="$CFLAGS -fvisibility=hidden"])
227
228AS_CASE([$host_os], [cygwin*|mingw*|msys|pw32*|cegcc*], [ ], [
229  AX_CHECK_COMPILE_FLAG([-fPIC], [CFLAGS="$CFLAGS -fPIC"])
230])
231
232AS_IF([test "$enable_pie" != "no"],[
233  AX_CHECK_COMPILE_FLAG([-fPIE], [
234    AX_CHECK_LINK_FLAG([-pie], [
235      [CFLAGS="$CFLAGS -fPIE"
236       LDFLAGS="$LDFLAGS -pie"]
237    ])
238  ])
239])
240
241AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing], [CFLAGS="$CFLAGS -fno-strict-aliasing"])
242AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CFLAGS="$CFLAGS -fno-strict-overflow"], [
243  AX_CHECK_COMPILE_FLAG([-fwrapv], [CFLAGS="$CFLAGS -fwrapv"])
244])
245
246AS_IF([test "$GCC" = "yes" ], [
247  AS_CASE([$host_cpu],
248    [i?86|amd64|x86_64], [
249      AC_COMPILE_IFELSE(
250        [AC_LANG_SOURCE([
251#if !defined(__clang__) && defined(__GNUC__) && ((__GNUC__ << 8) | __GNUC_MINOR__) < 0x403
252# error old gcc
253#endif
254int main(void) { return 0; }
255         ])],,[
256          AX_CHECK_COMPILE_FLAG([-flax-vector-conversions], [CFLAGS="$CFLAGS -flax-vector-conversions"])
257        ])
258      ]
259    )
260  ])
261
262LIBTOOL_OLD_FLAGS="$LIBTOOL_EXTRA_FLAGS"
263LIBTOOL_EXTRA_FLAGS="$LIBTOOL_EXTRA_FLAGS -version-info $SODIUM_LIBRARY_VERSION"
264AC_ARG_ENABLE(soname-versions,
265  [AC_HELP_STRING([--enable-soname-versions], [enable soname versions (must be disabled for Android) (default: enabled)])],
266    [
267        AS_IF([test "x$enableval" = "xno"], [
268          LIBTOOL_EXTRA_FLAGS="$LIBTOOL_OLD_FLAGS -avoid-version"
269        ])
270    ]
271)
272
273AS_CASE([$host_os],
274  [cygwin*|mingw*|msys|pw32*|cegcc*], [
275    AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"])
276    AX_CHECK_LINK_FLAG([-Wl,--high-entropy-va], [LDFLAGS="$LDFLAGS -Wl,--high-entropy-va"])
277    AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [LDFLAGS="$LDFLAGS -Wl,--nxcompat"])
278  ])
279
280AS_CASE([$host_os],
281  [cygwin*|mingw*|msys|pw32*|cegcc*], [
282    AX_CHECK_COMPILE_FLAG([-fno-asynchronous-unwind-tables], [
283      [CFLAGS="$CFLAGS -fno-asynchronous-unwind-tables"]
284    ])
285])
286
287AS_IF([test "x$enable_ssp" != "xno"],[
288
289AS_CASE([$host_os],
290  [cygwin*|mingw*|msys|pw32*|cegcc*|haiku|none], [ ],
291  [*], [
292    AX_CHECK_COMPILE_FLAG([-fstack-protector], [
293      AX_CHECK_LINK_FLAG([-fstack-protector],
294        [CFLAGS="$CFLAGS -fstack-protector"]
295      )
296    ])
297  ])
298])
299
300AC_ARG_VAR([CWFLAGS], [define to compilation flags for generating extra warnings])
301
302AX_CHECK_COMPILE_FLAG([$CFLAGS -Wall], [CWFLAGS="$CFLAGS -Wall"])
303AX_CHECK_COMPILE_FLAG([$CFLAGS -Wextra], [CWFLAGS="$CFLAGS -Wextra"])
304
305AC_MSG_CHECKING(for clang)
306AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
307#ifndef __clang__
308#error Not clang
309#endif
310]])],
311  [AC_MSG_RESULT(yes)
312   AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wno-unknown-warning-option],
313     [CWFLAGS="$CWFLAGS -Wno-unknown-warning-option"])
314  ],
315  [AC_MSG_RESULT(no)
316])
317
318AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wbad-function-cast], [CWFLAGS="$CWFLAGS -Wbad-function-cast"])
319AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wcast-qual], [CWFLAGS="$CWFLAGS -Wcast-qual"])
320AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wdiv-by-zero], [CWFLAGS="$CWFLAGS -Wdiv-by-zero"])
321AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wduplicated-branches], [CWFLAGS="$CWFLAGS -Wduplicated-branches"])
322AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wduplicated-cond], [CWFLAGS="$CWFLAGS -Wduplicated-cond"])
323AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wfloat-equal], [CWFLAGS="$CWFLAGS -Wfloat-equal"])
324AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wformat=2], [CWFLAGS="$CWFLAGS -Wformat=2"])
325AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wlogical-op], [CWFLAGS="$CWFLAGS -Wlogical-op"])
326AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmaybe-uninitialized], [CWFLAGS="$CWFLAGS -Wmaybe-uninitialized"])
327AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmisleading-indentation], [CWFLAGS="$CWFLAGS -Wmisleading-indentation"])
328AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmissing-declarations], [CWFLAGS="$CWFLAGS -Wmissing-declarations"])
329AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmissing-prototypes], [CWFLAGS="$CWFLAGS -Wmissing-prototypes"])
330AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wnested-externs], [CWFLAGS="$CWFLAGS -Wnested-externs"])
331AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wno-type-limits], [CWFLAGS="$CWFLAGS -Wno-type-limits"])
332AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wno-unknown-pragmas], [CWFLAGS="$CWFLAGS -Wno-unknown-pragmas"])
333AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wnormalized=id], [CWFLAGS="$CWFLAGS -Wnormalized=id"])
334AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wnull-dereference], [CWFLAGS="$CWFLAGS -Wnull-dereference"])
335AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wold-style-declaration], [CWFLAGS="$CWFLAGS -Wold-style-declaration"])
336AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wpointer-arith], [CWFLAGS="$CWFLAGS -Wpointer-arith"])
337AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wredundant-decls], [CWFLAGS="$CWFLAGS -Wredundant-decls"])
338AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wrestrict], [CWFLAGS="$CWFLAGS -Wrestrict"])
339AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wshorten-64-to-32], [CWFLAGS="$CWFLAGS -Wshorten-64-to-32"])
340AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wsometimes-uninitialized], [CWFLAGS="$CWFLAGS -Wsometimes-uninitialized"])
341AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wstrict-prototypes], [CWFLAGS="$CWFLAGS -Wstrict-prototypes"])
342AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wswitch-enum], [CWFLAGS="$CWFLAGS -Wswitch-enum"])
343AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wvariable-decl], [CWFLAGS="$CWFLAGS -Wvariable-decl"])
344AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wwrite-strings], [CWFLAGS="$CWFLAGS -Wwrite-strings"])
345
346AX_CHECK_LINK_FLAG([-Wl,-z,relro], [LDFLAGS="$LDFLAGS -Wl,-z,relro"])
347AX_CHECK_LINK_FLAG([-Wl,-z,now], [LDFLAGS="$LDFLAGS -Wl,-z,now"])
348AX_CHECK_LINK_FLAG([-Wl,-z,noexecstack], [LDFLAGS="$LDFLAGS -Wl,-z,noexecstack"])
349
350AX_CHECK_CATCHABLE_SEGV
351AX_CHECK_CATCHABLE_ABRT
352
353AS_IF([test "x$with_threads" = "xyes"], [
354  AX_TLS([AC_MSG_RESULT(thread local storage is supported)
355          AX_CHECK_COMPILE_FLAG([-ftls-model=local-dynamic],
356            [CFLAGS="$CFLAGS -ftls-model=local-dynamic"])],
357         [AC_MSG_RESULT(thread local storage is not supported)]) ])
358
359LT_INIT
360AC_SUBST(LIBTOOL_DEPS)
361
362AC_ARG_VAR([AR], [path to the ar utility])
363AC_CHECK_TOOL([AR], [ar], [ar])
364
365dnl Checks for headers
366
367AS_IF([test "x$EMSCRIPTEN" = "x"], [
368
369  oldcflags="$CFLAGS"
370  AX_CHECK_COMPILE_FLAG([-mmmx], [CFLAGS="$CFLAGS -mmmx"])
371  AC_MSG_CHECKING(for MMX instructions set)
372  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
373#pragma GCC target("mmx")
374#include <mmintrin.h>
375]], [[ __m64 x = _mm_setzero_si64(); ]])],
376    [AC_MSG_RESULT(yes)
377     AC_DEFINE([HAVE_MMINTRIN_H], [1], [mmx is available])
378     AX_CHECK_COMPILE_FLAG([-mmmx], [CFLAGS_MMX="-mmmx"])],
379    [AC_MSG_RESULT(no)])
380  CFLAGS="$oldcflags"
381
382  oldcflags="$CFLAGS"
383  AX_CHECK_COMPILE_FLAG([-msse2], [CFLAGS="$CFLAGS -msse2"])
384  AC_MSG_CHECKING(for SSE2 instructions set)
385  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
386#pragma GCC target("sse2")
387#ifndef __SSE2__
388# define __SSE2__
389#endif
390#include <emmintrin.h>
391]], [[ __m128d x = _mm_setzero_pd();
392       __m128i z = _mm_srli_epi64(_mm_setzero_si128(), 26); ]])],
393    [AC_MSG_RESULT(yes)
394     AC_DEFINE([HAVE_EMMINTRIN_H], [1], [sse2 is available])
395     AX_CHECK_COMPILE_FLAG([-msse2], [CFLAGS_SSE2="-msse2"])],
396    [AC_MSG_RESULT(no)])
397  CFLAGS="$oldcflags"
398
399  oldcflags="$CFLAGS"
400  AX_CHECK_COMPILE_FLAG([-msse3], [CFLAGS="$CFLAGS -msse3"])
401  AC_MSG_CHECKING(for SSE3 instructions set)
402  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
403#pragma GCC target("sse3")
404#include <pmmintrin.h>
405]], [[ __m128 x = _mm_addsub_ps(_mm_cvtpd_ps(_mm_setzero_pd()),
406                                _mm_cvtpd_ps(_mm_setzero_pd())); ]])],
407    [AC_MSG_RESULT(yes)
408     AC_DEFINE([HAVE_PMMINTRIN_H], [1], [sse3 is available])
409     AX_CHECK_COMPILE_FLAG([-msse3], [CFLAGS_SSE3="-msse3"])],
410    [AC_MSG_RESULT(no)])
411  CFLAGS="$oldcflags"
412
413  oldcflags="$CFLAGS"
414  AX_CHECK_COMPILE_FLAG([-mssse3], [CFLAGS="$CFLAGS -mssse3"])
415  AC_MSG_CHECKING(for SSSE3 instructions set)
416  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
417#pragma GCC target("ssse3")
418#include <tmmintrin.h>
419]], [[ __m64 x = _mm_abs_pi32(_m_from_int(0)); ]])],
420    [AC_MSG_RESULT(yes)
421     AC_DEFINE([HAVE_TMMINTRIN_H], [1], [ssse3 is available])
422     AX_CHECK_COMPILE_FLAG([-mssse3], [CFLAGS_SSSE3="-mssse3"])],
423    [AC_MSG_RESULT(no)])
424  CFLAGS="$oldcflags"
425
426  oldcflags="$CFLAGS"
427  AX_CHECK_COMPILE_FLAG([-msse4.1], [CFLAGS="$CFLAGS -msse4.1"])
428  AC_MSG_CHECKING(for SSE4.1 instructions set)
429  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
430#pragma GCC target("sse4.1")
431#include <smmintrin.h>
432]], [[ __m128i x = _mm_minpos_epu16(_mm_setzero_si128()); ]])],
433    [AC_MSG_RESULT(yes)
434     AC_DEFINE([HAVE_SMMINTRIN_H], [1], [sse4.1 is available])
435     AX_CHECK_COMPILE_FLAG([-msse4.1], [CFLAGS_SSE41="-msse4.1"])],
436    [AC_MSG_RESULT(no)])
437  CFLAGS="$oldcflags"
438
439  oldcflags="$CFLAGS"
440  AX_CHECK_COMPILE_FLAG([-mavx], [CFLAGS="$CFLAGS -mavx"])
441  AC_MSG_CHECKING(for AVX instructions set)
442  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
443#pragma GCC target("avx")
444#include <immintrin.h>
445]], [[ _mm256_zeroall(); ]])],
446    [AC_MSG_RESULT(yes)
447     AC_DEFINE([HAVE_AVXINTRIN_H], [1], [AVX is available])
448     AX_CHECK_COMPILE_FLAG([-mavx], [CFLAGS_AVX="-mavx"])],
449    [AC_MSG_RESULT(no)])
450  CFLAGS="$oldcflags"
451
452  oldcflags="$CFLAGS"
453  AX_CHECK_COMPILE_FLAG([-mavx2], [CFLAGS="$CFLAGS -mavx2"])
454  AC_MSG_CHECKING(for AVX2 instructions set)
455  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
456#pragma GCC target("avx2")
457#include <immintrin.h>
458]], [[
459__m256 x = _mm256_set1_ps(3.14);
460__m256 y = _mm256_permutevar8x32_ps(x, _mm256_set1_epi32(42));
461return _mm256_movemask_ps(_mm256_cmp_ps(x, y, _CMP_NEQ_OQ));
462]])],
463    [AC_MSG_RESULT(yes)
464     AC_DEFINE([HAVE_AVX2INTRIN_H], [1], [AVX2 is available])
465     AX_CHECK_COMPILE_FLAG([-mavx2], [CFLAGS_AVX2="-mavx2"])
466     AC_MSG_CHECKING(if _mm256_broadcastsi128_si256 is correctly defined)
467     AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
468#pragma GCC target("avx2")
469#include <immintrin.h>
470     ]], [[ __m256i y = _mm256_broadcastsi128_si256(_mm_setzero_si128()); ]])],
471       [AC_MSG_RESULT(yes)],
472       [AC_MSG_RESULT(no)
473        AC_DEFINE([_mm256_broadcastsi128_si256], [_mm_broadcastsi128_si256],
474                  [Define to the local name of _mm256_broadcastsi128_si256])])
475     ],
476    [AC_MSG_RESULT(no)])
477  CFLAGS="$oldcflags"
478
479  oldcflags="$CFLAGS"
480  AX_CHECK_COMPILE_FLAG([-mavx512f], [CFLAGS="$CFLAGS -mavx512f"])
481  AC_MSG_CHECKING(for AVX512F instructions set)
482  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
483#pragma GCC target("avx512f")
484#include <immintrin.h>
485]], [[
486
487#ifndef __AVX512F__
488# error No AVX512 support
489#elif defined(__clang__)
490# if __clang_major__ < 4
491#  error Compiler AVX512 support may be broken
492# endif
493#elif defined(__GNUC__)
494# if __GNUC__ < 6
495#  error Compiler AVX512 support may be broken
496# endif
497#endif
498
499__m512i x = _mm512_setzero_epi32();
500__m512i y = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), x);
501]])],
502    [AC_MSG_RESULT(yes)
503     AC_DEFINE([HAVE_AVX512FINTRIN_H], [1], [AVX512F is available])
504     AX_CHECK_COMPILE_FLAG([-mavx512f], [CFLAGS_AVX512F="-mavx512f"])],
505    [AC_MSG_RESULT(no)
506     AX_CHECK_COMPILE_FLAG([$CFLAGS -mno-avx512f],
507       [CFLAGS="$CFLAGS -mno-avx512f"])
508    ])
509  CFLAGS="$oldcflags"
510
511  oldcflags="$CFLAGS"
512  AX_CHECK_COMPILE_FLAG([-maes], [CFLAGS="$CFLAGS -maes"])
513  AX_CHECK_COMPILE_FLAG([-mpclmul], [CFLAGS="$CFLAGS -mpclmul"])
514  AC_MSG_CHECKING(for AESNI instructions set and PCLMULQDQ)
515  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
516#pragma GCC target("aes")
517#pragma GCC target("pclmul")
518#include <wmmintrin.h>
519]], [[ __m128i x = _mm_aesimc_si128(_mm_setzero_si128());
520       __m128i y = _mm_clmulepi64_si128(_mm_setzero_si128(), _mm_setzero_si128(), 0);]])],
521    [AC_MSG_RESULT(yes)
522     AC_DEFINE([HAVE_WMMINTRIN_H], [1], [aesni is available])
523     AX_CHECK_COMPILE_FLAG([-maes], [CFLAGS_AESNI="-maes"])
524     AX_CHECK_COMPILE_FLAG([-mpclmul], [CFLAGS_PCLMUL="-mpclmul"])
525     ],
526    [AC_MSG_RESULT(no)])
527  CFLAGS="$oldcflags"
528
529  oldcflags="$CFLAGS"
530  AX_CHECK_COMPILE_FLAG([-mrdrnd], [CFLAGS="$CFLAGS -mrdrnd"])
531  AC_MSG_CHECKING(for RDRAND)
532  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
533#pragma GCC target("rdrnd")
534#include <immintrin.h>
535]], [[ unsigned long long x; _rdrand64_step(&x); ]])],
536    [AC_MSG_RESULT(yes)
537     AC_DEFINE([HAVE_RDRAND], [1], [rdrand is available])
538     AX_CHECK_COMPILE_FLAG([-mrdrnd], [CFLAGS_RDRAND="-mrdrnd"])
539     ],
540    [AC_MSG_RESULT(no)])
541  CFLAGS="$oldcflags"
542
543])
544
545AC_SUBST(CFLAGS_MMX)
546AC_SUBST(CFLAGS_SSE2)
547AC_SUBST(CFLAGS_SSE3)
548AC_SUBST(CFLAGS_SSSE3)
549AC_SUBST(CFLAGS_SSE41)
550AC_SUBST(CFLAGS_AVX)
551AC_SUBST(CFLAGS_AVX2)
552AC_SUBST(CFLAGS_AVX512F)
553AC_SUBST(CFLAGS_AESNI)
554AC_SUBST(CFLAGS_PCLMUL)
555AC_SUBST(CFLAGS_RDRAND)
556
557AC_CHECK_HEADERS([sys/mman.h sys/random.h intrin.h])
558
559AC_MSG_CHECKING([if _xgetbv() is available])
560AC_LINK_IFELSE(
561  [AC_LANG_PROGRAM([[ #include <intrin.h> ]], [[ (void) _xgetbv(0) ]])],
562  [AC_MSG_RESULT(yes)
563   AC_DEFINE([HAVE__XGETBV], [1], [_xgetbv() is available])],
564  [AC_MSG_RESULT(no)])
565
566dnl Checks for typedefs, structures, and compiler characteristics.
567
568AC_C_INLINE
569AS_CASE([$host_cpu],
570  [i?86|amd64|x86_64],
571    [ac_cv_c_bigendian=no]
572)
573AC_C_BIGENDIAN(
574  AC_DEFINE(NATIVE_BIG_ENDIAN, 1, [machine is bigendian]),
575  AC_DEFINE(NATIVE_LITTLE_ENDIAN, 1, [machine is littleendian]),
576  AC_MSG_ERROR([unknown endianness]),
577  AC_MSG_ERROR([universal endianness is not supported - compile separately and use lipo(1)])
578)
579
580AC_MSG_CHECKING(whether __STDC_LIMIT_MACROS is required)
581AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
582#include <limits.h>
583#include <stdint.h>
584]], [[
585(void) SIZE_MAX;
586(void) UINT64_MAX;
587]])],
588  [AC_MSG_RESULT(no)],
589  [AC_MSG_RESULT(yes)
590   CPPFLAGS="$CPPFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS"
591])
592
593AC_MSG_CHECKING(whether we can use inline asm code)
594AC_LINK_IFELSE([AC_LANG_PROGRAM([[
595]], [[
596int a = 42;
597int *pnt = &a;
598__asm__ __volatile__ ("" : : "r"(pnt) : "memory");
599]])],
600  [AC_MSG_RESULT(yes)
601   AC_DEFINE([HAVE_INLINE_ASM], [1], [inline asm code can be used])]
602  [AC_MSG_RESULT(no)]
603)
604
605HAVE_AMD64_ASM_V=0
606AS_IF([test "$enable_asm" != "no"],[
607  AC_MSG_CHECKING(whether we can use x86_64 asm code)
608  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
609  ]], [[
610#if defined(__amd64) || defined(__amd64__) || defined(__x86_64__)
611# if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(_WIN32) || defined(_WIN64)
612#  error Windows x86_64 calling conventions are not supported yet
613# endif
614/* neat */
615#else
616# error !x86_64
617#endif
618unsigned char i = 0, o = 0, t;
619__asm__ __volatile__ ("pxor %%xmm12, %%xmm6 \n"
620                      "movb (%[i]), %[t] \n"
621                      "addb %[t], (%[o]) \n"
622                      : [t] "=&r"(t)
623                      : [o] "D"(&o), [i] "S"(&i)
624                      : "memory", "flags", "cc");
625]])],
626  [AC_MSG_RESULT(yes)
627   AC_DEFINE([HAVE_AMD64_ASM], [1], [x86_64 asm code can be used])
628   HAVE_AMD64_ASM_V=1],
629  [AC_MSG_RESULT(no)])
630])
631AM_CONDITIONAL([HAVE_AMD64_ASM], [test $HAVE_AMD64_ASM_V = 1])
632AC_SUBST(HAVE_AMD64_ASM_V)
633
634HAVE_AVX_ASM_V=0
635AS_IF([test "$enable_asm" != "no"],[
636  AC_MSG_CHECKING(whether we can assemble AVX opcodes)
637  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
638  ]], [[
639#if defined(__amd64) || defined(__amd64__) || defined(__x86_64__)
640# if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(_WIN32) || defined(_WIN64)
641#  error Windows x86_64 calling conventions are not supported yet
642# endif
643/* neat */
644#else
645# error !x86_64
646#endif
647__asm__ __volatile__ ("vpunpcklqdq %xmm0,%xmm13,%xmm0");
648]])],
649  [AC_MSG_RESULT(yes)
650   AC_DEFINE([HAVE_AVX_ASM], [1], [AVX opcodes are supported])
651   HAVE_AVX_ASM_V=1],
652  [AC_MSG_RESULT(no)])
653])
654AM_CONDITIONAL([HAVE_AVX_ASM], [test $HAVE_AVX_ASM_V = 1])
655AC_SUBST(HAVE_AVX_ASM_V)
656
657AC_MSG_CHECKING(for 128-bit arithmetic)
658HAVE_TI_MODE_V=0
659AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
660#if !defined(__clang__) && !defined(__GNUC__) && !defined(__SIZEOF_INT128__)
661# error mode(TI) is a gcc extension, and __int128 is not available
662#endif
663#if defined(__clang__) && !defined(__x86_64__) && !defined(__aarch64__)
664# error clang does not properly handle the 128-bit type on 32-bit systems
665#endif
666#ifndef NATIVE_LITTLE_ENDIAN
667# error libsodium currently expects a little endian CPU for the 128-bit type
668#endif
669#ifdef __EMSCRIPTEN__
670# error emscripten currently doesn't support some operations on integers larger than 64 bits
671#endif
672#include <stddef.h>
673#include <stdint.h>
674#if defined(__SIZEOF_INT128__)
675typedef unsigned __int128 uint128_t;
676#else
677typedef unsigned uint128_t __attribute__((mode(TI)));
678#endif
679void fcontract(uint128_t *t) {
680  *t += 0x8000000000000 - 1;
681  *t *= *t;
682  *t >>= 84;
683}
684]], [[
685(void) fcontract;
686]])],
687[AC_MSG_RESULT(yes)
688 AC_DEFINE([HAVE_TI_MODE], [1], [gcc TI mode is available])
689 HAVE_TI_MODE_V=1],
690[AC_MSG_RESULT(no)])
691AM_CONDITIONAL([HAVE_TI_MODE], [test $HAVE_TI_MODE_V = 1])
692AC_SUBST(HAVE_TI_MODE_V)
693
694HAVE_CPUID_V=0
695AS_IF([test "$enable_asm" != "no"],[
696  AC_MSG_CHECKING(for cpuid instruction)
697  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[
698unsigned int cpu_info[4];
699__asm__ __volatile__ ("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" :
700                      "=a" (cpu_info[0]), "=&r" (cpu_info[1]),
701                      "=c" (cpu_info[2]), "=d" (cpu_info[3]) :
702                      "0" (0U), "2" (0U));
703  ]])],
704  [AC_MSG_RESULT(yes)
705   AC_DEFINE([HAVE_CPUID], [1], [cpuid instruction is available])
706   HAVE_CPUID_V=1],
707  [AC_MSG_RESULT(no)])
708  ])
709AC_SUBST(HAVE_CPUID_V)
710
711asm_hide_symbol="unsupported"
712AS_IF([test "$enable_asm" != "no"],[
713  AC_MSG_CHECKING(if the .private_extern asm directive is supported)
714  AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[
715__asm__ __volatile__ (".private_extern dummy_symbol \n"
716                      ".private_extern _dummy_symbol \n"
717                      ".globl dummy_symbol \n"
718                      ".globl _dummy_symbol \n"
719                      "dummy_symbol: \n"
720                      "_dummy_symbol: \n"
721                      "    nop \n"
722);
723  ]])],
724  [AC_MSG_RESULT(yes)
725   asm_hide_symbol=".private_extern"],
726  [AC_MSG_RESULT(no)])
727
728  AC_MSG_CHECKING(if the .hidden asm directive is supported)
729  AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[
730__asm__ __volatile__ (".hidden dummy_symbol \n"
731                      ".hidden _dummy_symbol \n"
732                      ".globl dummy_symbol \n"
733                      ".globl _dummy_symbol \n"
734                      "dummy_symbol: \n"
735                      "_dummy_symbol: \n"
736                      "    nop \n"
737);
738  ]])],
739  [AC_MSG_RESULT(yes)
740   AS_IF([test "$asm_hide_symbol" = "unsupported"],
741          [asm_hide_symbol=".hidden"],
742          [AC_MSG_NOTICE([unable to reliably tag symbols as private])
743           asm_hide_symbol="unsupported"])
744  ],
745  [AC_MSG_RESULT(no)])
746
747  AS_IF([test "$asm_hide_symbol" != "unsupported"],[
748    AC_DEFINE_UNQUOTED([ASM_HIDE_SYMBOL], [$asm_hide_symbol], [directive to hide symbols])
749  ])
750])
751
752AC_MSG_CHECKING(if weak symbols are supported)
753AC_LINK_IFELSE([AC_LANG_PROGRAM([[
754#if !defined(__ELF__) && !defined(__APPLE_CC__)
755# error Support for weak symbols may not be available
756#endif
757__attribute__((weak)) void __dummy(void *x) { }
758void f(void *x) { __dummy(x); }
759]], [[ ]]
760)],
761[AC_MSG_RESULT(yes)
762 AC_DEFINE([HAVE_WEAK_SYMBOLS], [1], [weak symbols are supported])],
763[AC_MSG_RESULT(no)])
764
765AC_MSG_CHECKING(if data alignment is required)
766aligned_access_required=yes
767AS_CASE([$host_cpu],
768  [i?86|amd64|x86_64|powerpc*|s390*],
769    [aligned_access_required=no],
770  [arm*],
771    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
772#ifndef __ARM_FEATURE_UNALIGNED
773# error data alignment is required
774#endif
775      ]], [[]])], [aligned_access_required=no], [])]
776)
777AS_IF([test "x$aligned_access_required" = "xyes"],
778  [AC_MSG_RESULT(yes)],
779  [AC_MSG_RESULT(no)
780   AC_DEFINE([CPU_UNALIGNED_ACCESS], [1], [unaligned memory access is supported])])
781
782AC_MSG_CHECKING(if atomic operations are supported)
783AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[
784static volatile int _sodium_lock;
785__sync_lock_test_and_set(&_sodium_lock, 1);
786__sync_lock_release(&_sodium_lock);
787]]
788)],
789[AC_MSG_RESULT(yes)
790 AC_DEFINE([HAVE_ATOMIC_OPS], [1], [atomic operations are supported])],
791[AC_MSG_RESULT(no)])
792
793dnl Checks for functions and headers
794
795AC_FUNC_ALLOCA
796AS_IF([test "x$EMSCRIPTEN" = "x"],[
797  AC_CHECK_FUNCS([arc4random arc4random_buf])
798  AC_CHECK_FUNCS([mmap mlock madvise mprotect])
799
800  AC_MSG_CHECKING(for getrandom with a standard API)
801  AC_LINK_IFELSE([AC_LANG_PROGRAM([[
802#include <stdlib.h>
803#ifdef HAVE_UNISTD_H
804# include <unistd.h>
805#endif
806#ifdef HAVE_SYS_RANDOM_H
807# include <sys/random.h>
808#endif
809]], [[
810unsigned char buf;
811(void) getrandom((void *) &buf, 1U, 0U);
812  ]])],
813  [AC_MSG_RESULT(yes)
814   AC_CHECK_FUNCS([getrandom])],
815  [AC_MSG_RESULT(no)
816  ])
817
818  AC_MSG_CHECKING(for getentropy with a standard API)
819  AC_LINK_IFELSE([AC_LANG_PROGRAM([[
820#include <stdlib.h>
821#ifdef HAVE_UNISTD_H
822# include <unistd.h>
823#endif
824#ifdef HAVE_SYS_RANDOM_H
825# include <sys/random.h>
826#endif
827]], [[
828#ifdef __APPLE__
829# error getentropy() is currently disabled on Apple operating systems
830#endif
831
832unsigned char buf;
833(void) getentropy((void *) &buf, 1U);
834  ]])],
835  [AC_MSG_RESULT(yes)
836   AC_CHECK_FUNCS([getentropy])],
837  [AC_MSG_RESULT(no)
838  ])
839])
840AC_CHECK_FUNCS([posix_memalign getpid nanosleep])
841AC_CHECK_FUNCS([memset_s explicit_bzero explicit_memset])
842
843AC_SUBST([LIBTOOL_EXTRA_FLAGS])
844
845TEST_LDFLAGS=''
846AS_IF([test "x$EMSCRIPTEN" != "x"],[
847  EXEEXT=.js
848  TEST_LDFLAGS='--memory-init-file 0 --pre-js pre.js.inc -s RESERVED_FUNCTION_POINTERS=8'
849])
850AC_SUBST(TEST_LDFLAGS)
851AM_CONDITIONAL([EMSCRIPTEN], [test "x$EMSCRIPTEN" != "x"])
852AM_CONDITIONAL([WASI], [test "x$WASI" != "x"])
853
854AC_DEFINE([CONFIGURED], [1], [the build system was properly configured])
855
856dnl Libtool.
857
858LT_INIT([dlopen])
859AC_LIBTOOL_WIN32_DLL
860gl_LD_OUTPUT_DEF
861
862dnl Output.
863
864AH_VERBATIM([NDEBUG], [/* Always evaluate assert() calls */
865#ifdef NDEBUG
866#/**/undef/**/ NDEBUG
867#endif])
868
869AS_IF([test "x$ENABLE_CWFLAGS" = "xyes"], [
870  CFLAGS="$CFLAGS $CWFLAGS"
871])
872
873AC_CONFIG_FILES([Makefile
874                 builds/Makefile
875                 contrib/Makefile
876                 dist-build/Makefile
877                 libsodium.pc
878                 libsodium-uninstalled.pc
879                 msvc-scripts/Makefile
880                 src/Makefile
881                 src/libsodium/Makefile
882                 src/libsodium/include/Makefile
883                 src/libsodium/include/sodium/version.h
884                 test/default/Makefile
885                 test/Makefile
886                 ])
887AC_OUTPUT
888