# cmake bits to do a full static build, downloading and building all dependencies. # Most of these are CACHE STRINGs so that you can override them using -DWHATEVER during cmake # invocation to override. set(LOCAL_MIRROR "" CACHE STRING "local mirror path/URL for lib downloads") set(OPENSSL_VERSION 1.1.1l CACHE STRING "openssl version") set(OPENSSL_MIRROR ${LOCAL_MIRROR} https://www.openssl.org/source CACHE STRING "openssl download mirror(s)") set(OPENSSL_SOURCE openssl-${OPENSSL_VERSION}.tar.gz) set(OPENSSL_HASH SHA256=0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1 CACHE STRING "openssl source hash") set(EXPAT_VERSION 2.3.0 CACHE STRING "expat version") string(REPLACE "." "_" EXPAT_TAG "R_${EXPAT_VERSION}") set(EXPAT_MIRROR ${LOCAL_MIRROR} https://github.com/libexpat/libexpat/releases/download/${EXPAT_TAG} CACHE STRING "expat download mirror(s)") set(EXPAT_SOURCE expat-${EXPAT_VERSION}.tar.xz) set(EXPAT_HASH SHA512=dde8a9a094b18d795a0e86ca4aa68488b352dc67019e0d669e8b910ed149628de4c2a49bc3a5b832f624319336a01f9e4debe03433a43e1c420f36356d886820 CACHE STRING "expat source hash") set(UNBOUND_VERSION 1.13.1 CACHE STRING "unbound version") set(UNBOUND_MIRROR ${LOCAL_MIRROR} https://nlnetlabs.nl/downloads/unbound CACHE STRING "unbound download mirror(s)") set(UNBOUND_SOURCE unbound-${UNBOUND_VERSION}.tar.gz) set(UNBOUND_HASH SHA256=8504d97b8fc5bd897345c95d116e0ee0ddf8c8ff99590ab2b4bd13278c9f50b8 CACHE STRING "unbound source hash") set(SQLITE3_VERSION 3350500 CACHE STRING "sqlite3 version") set(SQLITE3_MIRROR ${LOCAL_MIRROR} https://www.sqlite.org/2021 CACHE STRING "sqlite3 download mirror(s)") set(SQLITE3_SOURCE sqlite-autoconf-${SQLITE3_VERSION}.tar.gz) set(SQLITE3_HASH SHA512=039af796f79fc4517be0bd5ba37886264d49da309e234ae6fccdb488ef0109ed2b917fc3e6c1fc7224dff4f736824c653aaf8f0a37550c5ebc14d035cb8ac737 CACHE STRING "sqlite3 source hash") set(SODIUM_VERSION 1.0.18 CACHE STRING "libsodium version") set(SODIUM_MIRROR ${LOCAL_MIRROR} https://download.libsodium.org/libsodium/releases https://github.com/jedisct1/libsodium/releases/download/${SODIUM_VERSION}-RELEASE CACHE STRING "libsodium mirror(s)") set(SODIUM_SOURCE libsodium-${SODIUM_VERSION}.tar.gz) set(SODIUM_HASH SHA512=17e8638e46d8f6f7d024fe5559eccf2b8baf23e143fadd472a7d29d228b186d86686a5e6920385fe2020729119a5f12f989c3a782afbd05a8db4819bb18666ef CACHE STRING "libsodium source hash") set(ZMQ_VERSION 4.3.4 CACHE STRING "libzmq version") set(ZMQ_MIRROR ${LOCAL_MIRROR} https://github.com/zeromq/libzmq/releases/download/v${ZMQ_VERSION} CACHE STRING "libzmq mirror(s)") set(ZMQ_SOURCE zeromq-${ZMQ_VERSION}.tar.gz) set(ZMQ_HASH SHA512=e198ef9f82d392754caadd547537666d4fba0afd7d027749b3adae450516bcf284d241d4616cad3cb4ad9af8c10373d456de92dc6d115b037941659f141e7c0e CACHE STRING "libzmq source hash") set(LIBUV_VERSION 1.41.0 CACHE STRING "libuv version") set(LIBUV_MIRROR ${LOCAL_MIRROR} https://dist.libuv.org/dist/v${LIBUV_VERSION} CACHE STRING "libuv mirror(s)") set(LIBUV_SOURCE libuv-v${LIBUV_VERSION}.tar.gz) set(LIBUV_HASH SHA512=33613fa28e8136507300eba374351774849b6b39aab4e53c997a918d3bc1d1094c6123e0e509535095b14dc5daa885eadb1a67bed46622ad3cc79d62dc817e84 CACHE STRING "libuv source hash") set(ZLIB_VERSION 1.2.11 CACHE STRING "zlib version") set(ZLIB_MIRROR ${LOCAL_MIRROR} https://zlib.net CACHE STRING "zlib mirror(s)") set(ZLIB_SOURCE zlib-${ZLIB_VERSION}.tar.gz) set(ZLIB_HASH SHA512=73fd3fff4adeccd4894084c15ddac89890cd10ef105dd5e1835e1e9bbb6a49ff229713bd197d203edfa17c2727700fce65a2a235f07568212d820dca88b528ae CACHE STRING "zlib source hash") set(CURL_VERSION 7.76.1 CACHE STRING "curl version") set(CURL_MIRROR ${LOCAL_MIRROR} https://curl.haxx.se/download https://curl.askapache.com CACHE STRING "curl mirror(s)") set(CURL_SOURCE curl-${CURL_VERSION}.tar.xz) set(CURL_HASH SHA256=64bb5288c39f0840c07d077e30d9052e1cbb9fa6c2dc52523824cc859e679145 CACHE STRING "curl source hash") include(ExternalProject) set(DEPS_DESTDIR ${CMAKE_BINARY_DIR}/static-deps) set(DEPS_SOURCEDIR ${CMAKE_BINARY_DIR}/static-deps-sources) include_directories(BEFORE SYSTEM ${DEPS_DESTDIR}/include) file(MAKE_DIRECTORY ${DEPS_DESTDIR}/include) set(deps_cc "${CMAKE_C_COMPILER}") set(deps_cxx "${CMAKE_CXX_COMPILER}") if(CMAKE_C_COMPILER_LAUNCHER) set(deps_cc "${CMAKE_C_COMPILER_LAUNCHER} ${deps_cc}") endif() if(CMAKE_CXX_COMPILER_LAUNCHER) set(deps_cxx "${CMAKE_CXX_COMPILER_LAUNCHER} ${deps_cxx}") endif() function(expand_urls output source_file) set(expanded) foreach(mirror ${ARGN}) list(APPEND expanded "${mirror}/${source_file}") endforeach() set(${output} "${expanded}" PARENT_SCOPE) endfunction() function(add_static_target target ext_target libname) add_library(${target} STATIC IMPORTED GLOBAL) add_dependencies(${target} ${ext_target}) set_target_properties(${target} PROPERTIES IMPORTED_LOCATION ${DEPS_DESTDIR}/lib/${libname} ) endfunction() set(cross_host "") set(cross_rc "") if(CMAKE_CROSSCOMPILING) set(cross_host "--host=${ARCH_TRIPLET}") if (ARCH_TRIPLET MATCHES mingw AND CMAKE_RC_COMPILER) set(cross_rc "WINDRES=${CMAKE_RC_COMPILER}") endif() endif() if(ANDROID) set(android_toolchain_suffix linux-android) set(android_compiler_suffix linux-android23) if(CMAKE_ANDROID_ARCH_ABI MATCHES x86_64) set(android_machine x86_64) set(cross_host "--host=x86_64-linux-android") set(android_compiler_prefix x86_64) set(android_compiler_suffix linux-android23) set(android_toolchain_prefix x86_64) set(android_toolchain_suffix linux-android) elseif(CMAKE_ANDROID_ARCH_ABI MATCHES x86) set(android_machine i686) set(cross_host "--host=i686-linux-android") set(android_compiler_prefix i686) set(android_compiler_suffix linux-android23) set(android_toolchain_prefix i686) set(android_toolchain_suffix linux-android) elseif(CMAKE_ANDROID_ARCH_ABI MATCHES armeabi-v7a) set(android_machine armv7) set(cross_host "--host=armv7a-linux-androideabi") set(android_compiler_prefix armv7a) set(android_compiler_suffix linux-androideabi23) set(android_toolchain_prefix arm) set(android_toolchain_suffix linux-androideabi) elseif(CMAKE_ANDROID_ARCH_ABI MATCHES arm64-v8a) set(android_machine aarch64) set(cross_host "--host=aarch64-linux-android") set(android_compiler_prefix aarch64) set(android_compiler_suffix linux-android23) set(android_toolchain_prefix aarch64) set(android_toolchain_suffix linux-android) else() message(FATAL_ERROR "unknown android arch: ${CMAKE_ANDROID_ARCH_ABI}") endif() set(deps_cc "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_compiler_prefix}-${android_compiler_suffix}-clang") set(deps_cxx "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_compiler_prefix}-${android_compiler_suffix}-clang++") set(deps_ld "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_compiler_prefix}-${android_toolchain_suffix}-ld") set(deps_ranlib "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_toolchain_prefix}-${android_toolchain_suffix}-ranlib") set(deps_ar "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin/${android_toolchain_prefix}-${android_toolchain_suffix}-ar") endif() set(deps_CFLAGS "-O2") set(deps_CXXFLAGS "-O2") if(WITH_LTO) set(deps_CFLAGS "${deps_CFLAGS} -flto") endif() if(APPLE) set(deps_CFLAGS "${deps_CFLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") set(deps_CXXFLAGS "${deps_CXXFLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") endif() if("${CMAKE_GENERATOR}" STREQUAL "Unix Makefiles") set(_make $(MAKE)) else() set(_make make) endif() # Builds a target; takes the target name (e.g. "readline") and builds it in an external project with # target name suffixed with `_external`. Its upper-case value is used to get the download details # (from the variables set above). The following options are supported and passed through to # ExternalProject_Add if specified. If omitted, these defaults are used: set(build_def_DEPENDS "") set(build_def_PATCH_COMMAND "") set(build_def_CONFIGURE_COMMAND ./configure ${cross_host} --disable-shared --prefix=${DEPS_DESTDIR} --with-pic "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" ${cross_rc}) set(build_def_BUILD_COMMAND ${_make}) set(build_def_INSTALL_COMMAND ${_make} install) set(build_def_BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/lib___TARGET___.a ${DEPS_DESTDIR}/include/___TARGET___.h) function(build_external target) set(options DEPENDS PATCH_COMMAND CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND BUILD_BYPRODUCTS) cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "${options}") foreach(o ${options}) if(NOT DEFINED arg_${o}) set(arg_${o} ${build_def_${o}}) endif() endforeach() string(REPLACE ___TARGET___ ${target} arg_BUILD_BYPRODUCTS "${arg_BUILD_BYPRODUCTS}") string(TOUPPER "${target}" prefix) expand_urls(urls ${${prefix}_SOURCE} ${${prefix}_MIRROR}) ExternalProject_Add("${target}_external" DEPENDS ${arg_DEPENDS} BUILD_IN_SOURCE ON PREFIX ${DEPS_SOURCEDIR} URL ${urls} URL_HASH ${${prefix}_HASH} DOWNLOAD_NO_PROGRESS ON PATCH_COMMAND ${arg_PATCH_COMMAND} CONFIGURE_COMMAND ${arg_CONFIGURE_COMMAND} BUILD_COMMAND ${arg_BUILD_COMMAND} INSTALL_COMMAND ${arg_INSTALL_COMMAND} BUILD_BYPRODUCTS ${arg_BUILD_BYPRODUCTS} ) endfunction() build_external(libuv CONFIGURE_COMMAND ./autogen.sh && ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --with-pic --disable-shared --enable-static "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/libuv.a ${DEPS_DESTDIR}/include/uv.h ) add_static_target(libuv libuv_external libuv.a) target_link_libraries(libuv INTERFACE ${CMAKE_DL_LIBS}) build_external(zlib CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS} -fPIC" ${cross_extra} ./configure --prefix=${DEPS_DESTDIR} --static BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/libz.a ${DEPS_DESTDIR}/include/zlib.h ) add_static_target(zlib zlib_external libz.a) set(openssl_system_env "") if(CMAKE_CROSSCOMPILING) if(ARCH_TRIPLET STREQUAL x86_64-w64-mingw32) set(openssl_system_env SYSTEM=MINGW64 RC=${CMAKE_RC_COMPILER} AR=${ARCH_TRIPLET}-ar RANLIB=${ARCH_TRIPLET}-ranlib) elseif(ARCH_TRIPLET STREQUAL i686-w64-mingw32) set(openssl_system_env SYSTEM=MINGW32 RC=${CMAKE_RC_COMPILER} AR=${ARCH_TRIPLET}-ar RANLIB=${ARCH_TRIPLET}-ranlib) elseif(ANDROID) set(openssl_system_env SYSTEM=Linux MACHINE=${android_machine} LD=${deps_ld} RANLIB=${deps_ranlib} AR=${deps_ar}) set(openssl_extra_opts no-asm) endif() elseif(CMAKE_C_FLAGS MATCHES "-march=armv7") # Help openssl figure out that we're building from armv7 even if on armv8 hardware: set(openssl_system_env SYSTEM=Linux MACHINE=armv7) endif() build_external(openssl CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${deps_cc} ${openssl_system_env} ./config --prefix=${DEPS_DESTDIR} ${openssl_extra_opts} no-shared no-capieng no-dso no-dtls1 no-ec_nistp_64_gcc_128 no-gost no-heartbeats no-md2 no-rc5 no-rdrand no-rfc3779 no-sctp no-ssl-trace no-ssl2 no-ssl3 no-static-engine no-tests no-weak-ssl-ciphers no-zlib no-zlib-dynamic "CFLAGS=${deps_CFLAGS}" INSTALL_COMMAND ${_make} install_sw BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/libssl.a ${DEPS_DESTDIR}/lib/libcrypto.a ${DEPS_DESTDIR}/include/openssl/ssl.h ${DEPS_DESTDIR}/include/openssl/crypto.h ) add_static_target(OpenSSL::SSL openssl_external libssl.a) add_static_target(OpenSSL::Crypto openssl_external libcrypto.a) if(WIN32) target_link_libraries(OpenSSL::Crypto INTERFACE "ws2_32;crypt32;iphlpapi") endif() set(OPENSSL_INCLUDE_DIR ${DEPS_DESTDIR}/include) set(OPENSSL_CRYPTO_LIBRARY ${DEPS_DESTDIR}/lib/libcrypto.a ${DEPS_DESTDIR}/lib/libssl.a) set(OPENSSL_VERSION 1.1.1) set(OPENSSL_ROOT_DIR ${DEPS_DESTDIR}) build_external(expat CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --enable-static --disable-shared --with-pic --without-examples --without-tests --without-docbook --without-xmlwf "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ) add_static_target(expat expat_external libexpat.a) build_external(unbound DEPENDS openssl_external expat_external CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-libunbound-only --with-pic --$,enable,disable>-flto --with-ssl=${DEPS_DESTDIR} --with-libexpat=${DEPS_DESTDIR} "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ) add_static_target(libunbound unbound_external libunbound.a) if(NOT WIN32) set_target_properties(libunbound PROPERTIES INTERFACE_LINK_LIBRARIES "OpenSSL::SSL;OpenSSL::Crypto") else() set_target_properties(libunbound PROPERTIES INTERFACE_LINK_LIBRARIES "OpenSSL::SSL;OpenSSL::Crypto;ws2_32;crypt32;iphlpapi") endif() build_external(sodium CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-pic "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}") add_static_target(sodium sodium_external libsodium.a) build_external(sqlite3) add_static_target(sqlite3 sqlite3_external libsqlite3.a) if(ARCH_TRIPLET MATCHES mingw) option(WITH_WEPOLL "use wepoll zmq poller (crashy)" OFF) if(WITH_WEPOLL) set(zmq_extra --with-poller=wepoll) endif() endif() if(CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw) set(zmq_patch PATCH_COMMAND ${PROJECT_SOURCE_DIR}/contrib/apply-patches.sh ${PROJECT_SOURCE_DIR}/contrib/patches/libzmq-mingw-wepoll.patch ${PROJECT_SOURCE_DIR}/contrib/patches/libzmq-mingw-closesocket.patch) endif() build_external(zmq DEPENDS sodium_external ${zmq_patch} CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --enable-static --disable-shared --disable-curve-keygen --enable-curve --disable-drafts --disable-libunwind --with-libsodium --without-pgm --without-norm --without-vmci --without-docs --with-pic --disable-Werror --disable-libbsd ${zmq_extra} "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS} -fstack-protector" "CXXFLAGS=${deps_CXXFLAGS} -fstack-protector" "sodium_CFLAGS=-I${DEPS_DESTDIR}/include" "sodium_LIBS=-L${DEPS_DESTDIR}/lib -lsodium" ) add_static_target(libzmq zmq_external libzmq.a) set(libzmq_link_libs "sodium") if(CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw) list(APPEND libzmq_link_libs iphlpapi) endif() set_target_properties(libzmq PROPERTIES INTERFACE_LINK_LIBRARIES "${libzmq_link_libs}" INTERFACE_COMPILE_DEFINITIONS "ZMQ_STATIC") set(curl_extra) if(WIN32) set(curl_ssl_opts --without-ssl --with-schannel) elseif(APPLE) set(curl_ssl_opts --without-ssl --with-secure-transport) if(IOS) # This CPP crap shouldn't be necessary but is because Apple's toolchain is trash set(curl_extra "LDFLAGS=-L${DEPS_DESTDIR}/lib -isysroot ${CMAKE_OSX_SYSROOT}" CPP=cpp) endif() else() set(curl_ssl_opts --with-ssl=${DEPS_DESTDIR}) set(curl_extra "LIBS=-pthread") endif() set(curl_arches default) set(curl_lib_outputs) if(IOS) # On iOS things get a little messy: curl won't build a multi-arch library (with `clang -arch arch1 # -arch arch2`) so we have to build them separately then glue them together if we're building # multiple. set(curl_arches ${CMAKE_OSX_ARCHITECTURES}) list(GET curl_arches 0 curl_arch0) list(LENGTH CMAKE_OSX_ARCHITECTURES num_arches) endif() foreach(curl_arch ${curl_arches}) set(curl_target_suffix "") set(curl_prefix "${DEPS_DESTDIR}") if(curl_arch STREQUAL "default") set(curl_cflags_extra "") elseif(IOS) set(cflags_extra " -arch ${curl_arch}") if(num_arches GREATER 1) set(curl_target_suffix "-${curl_arch}") set(curl_prefix "${DEPS_DESTDIR}/tmp/${curl_arch}") endif() else() message(FATAL_ERROR "unexpected curl_arch=${curl_arch}") endif() build_external(curl TARGET_SUFFIX ${curl_target_suffix} DEPENDS openssl_external zlib_external CONFIGURE_COMMAND ./configure ${cross_host} ${cross_extra} --prefix=${curl_prefix} --disable-shared --enable-static --disable-ares --disable-ftp --disable-ldap --disable-laps --disable-rtsp --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual --disable-libcurl-option --enable-http --enable-ipv6 --disable-threaded-resolver --disable-pthreads --disable-verbose --disable-sspi --enable-crypto-auth --disable-ntlm-wb --disable-tls-srp --disable-unix-sockets --disable-cookies --enable-http-auth --enable-doh --disable-mime --enable-dateparse --disable-netrc --without-libidn2 --disable-progress-meter --without-brotli --with-zlib=${DEPS_DESTDIR} ${curl_ssl_opts} --without-libmetalink --without-librtmp --disable-versioned-symbols --enable-hidden-symbols --without-zsh-functions-dir --without-fish-functions-dir --without-nghttp3 --without-zstd "CC=${deps_cc}" "CFLAGS=${deps_noarch_CFLAGS}${cflags_extra}" ${curl_extra} BUILD_COMMAND true INSTALL_COMMAND ${_make} -C lib install && ${_make} -C include install BUILD_BYPRODUCTS ${curl_prefix}/lib/libcurl.a ${curl_prefix}/include/curl/curl.h ) list(APPEND curl_lib_targets curl${curl_target_suffix}_external) list(APPEND curl_lib_outputs ${curl_prefix}/lib/libcurl.a) endforeach() message(STATUS "TARGETS: ${curl_lib_targets}") if(IOS AND num_arches GREATER 1) # We are building multiple architectures for different iOS devices, so we need to glue the # separate libraries into one. (Normally multiple -arch values passed to clang does this for us, # but curl refuses to build that way). add_custom_target(curl_external COMMAND lipo ${curl_lib_outputs} -create -output ${DEPS_DESTDIR}/libcurl.a COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_DESTDIR}/tmp/${curl_arch0}/include/curl ${DEPS_DESTDIR}/include/curl BYPRODUCTS ${DEPS_DESTDIR}/lib/libcurl.a ${DEPS_DESTDIR}/include/curl/curl.h DEPENDS ${curl_lib_targets}) endif() add_static_target(CURL::libcurl curl_external libcurl.a) set(libcurl_link_libs zlib) if(CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw) list(APPEND libcurl_link_libs crypt32) elseif(APPLE) list(APPEND libcurl_link_libs "-framework Security -framework CoreFoundation") endif() set_target_properties(CURL::libcurl PROPERTIES INTERFACE_LINK_LIBRARIES "${libcurl_link_libs}" INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")