From daaa8dbefd3a4792811ef227397e8dad4809c6dc Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 30 Oct 2020 13:33:23 -0300 Subject: [PATCH] Lots of build hacks for iOS --- cmake/StaticBuild.cmake | 171 ++++++++++++++---- external/CMakeLists.txt | 2 +- src/CMakeLists.txt | 22 +-- src/crypto/cn_heavy_hash_hard_arm.cpp | 6 + src/wallet/api/CMakeLists.txt | 25 ++- .../boost-darwin-libtool-path.patch | 11 ++ 6 files changed, 181 insertions(+), 56 deletions(-) create mode 100644 utils/build_scripts/boost-darwin-libtool-path.patch diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake index bdf629cb9..6aaf9a619 100644 --- a/cmake/StaticBuild.cmake +++ b/cmake/StaticBuild.cmake @@ -185,9 +185,13 @@ if (ANDROID) set(cross_host "--host=${CMAKE_LIBRARY_ARCHITECTURE}") set(cross_extra "LD=${ANDROID_TOOLCHAIN_ROOT}/bin/${CMAKE_LIBRARY_ARCHITECTURE}-ld" "RANLIB=${CMAKE_RANLIB}" "AR=${CMAKE_AR}") elseif(CMAKE_CROSSCOMPILING) - set(cross_host "--host=${ARCH_TRIPLET}") - if (ARCH_TRIPLET MATCHES mingw AND CMAKE_RC_COMPILER) - set(cross_extra "WINDRES=${CMAKE_RC_COMPILER}") + if(APPLE) + set(cross_host "--host=${APPLE_TARGET_TRIPLE}") + else() + set(cross_host "--host=${ARCH_TRIPLET}") + if (ARCH_TRIPLET MATCHES mingw AND CMAKE_RC_COMPILER) + set(cross_extra "WINDRES=${CMAKE_RC_COMPILER}") + endif() endif() endif() @@ -195,10 +199,19 @@ endif() set(deps_CFLAGS "-O2 ${flto}") set(deps_CXXFLAGS "-O2 ${flto}") +set(deps_noarch_CFLAGS "${deps_CFLAGS}") +set(deps_noarch_CXXFLAGS "${deps_CXXFLAGS}") 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}") + foreach(lang C CXX) + string(APPEND deps_${lang}FLAGS " ${CMAKE_${lang}_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT} ${CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") + + set(deps_noarch_${lang}FLAGS "${deps_${lang}FLAGS}") + + foreach(arch ${CMAKE_OSX_ARCHITECTURES}) + string(APPEND deps_${lang}FLAGS " -arch ${arch}") + endforeach() + endforeach() endif() # Builds a target; takes the target name (e.g. "readline") and builds it in an external project with @@ -212,9 +225,10 @@ set(build_def_CONFIGURE_COMMAND ./configure ${cross_host} --disable-shared --pre 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) +set(build_dep_TARGET_SUFFIX "") function(build_external target) - set(options DEPENDS PATCH_COMMAND CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND BUILD_BYPRODUCTS) + set(options TARGET_SUFFIX 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}) @@ -225,7 +239,7 @@ function(build_external target) string(TOUPPER "${target}" prefix) expand_urls(urls ${${prefix}_SOURCE} ${${prefix}_MIRROR}) - ExternalProject_Add("${target}_external" + ExternalProject_Add("${target}${arg_TARGET_SUFFIX}_external" DEPENDS ${arg_DEPENDS} BUILD_IN_SOURCE ON PREFIX ${DEPS_SOURCEDIR} @@ -252,7 +266,9 @@ add_static_target(zlib zlib_external libz.a) +set(openssl_configure ./config) set(openssl_system_env "") +set(openssl_cc "${deps_cc}") if(CMAKE_CROSSCOMPILING) if(ARCH_TRIPLET STREQUAL x86_64-w64-mingw32) set(openssl_system_env SYSTEM=MINGW64 RC=${CMAKE_RC_COMPILER}) @@ -261,10 +277,19 @@ if(CMAKE_CROSSCOMPILING) elseif(ANDROID) set(openssl_system_env SYSTEM=Linux MACHINE=${openssl_machine} ${cross_extra}) set(openssl_extra_opts no-asm) + elseif(IOS) + get_filename_component(apple_toolchain "${CMAKE_C_COMPILER}" DIRECTORY) + get_filename_component(apple_sdk "${CMAKE_OSX_SYSROOT}" NAME) + if(NOT ${apple_toolchain} MATCHES Xcode OR NOT ${apple_sdk} MATCHES "iPhone(OS|Simulator)") + message(FATAL_ERROR "didn't find your toolchain and sdk correctly from ${CMAKE_C_COMPILER}/${CMAKE_OSX_SYSROOT}: found toolchain=${apple_toolchain}, sdk=${apple_sdk}") + endif() + set(openssl_system_env CROSS_COMPILE=${apple_toolchain}/ CROSS_TOP=${CMAKE_DEVELOPER_ROOT} CROSS_SDK=${apple_sdk}) + set(openssl_configure ./Configure iphoneos-cross) + set(openssl_cc "clang") endif() endif() build_external(openssl - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${deps_cc} ${openssl_system_env} ./config + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${openssl_cc} ${openssl_system_env} ${openssl_configure} --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-dynamic "CFLAGS=${deps_CFLAGS}" @@ -291,7 +316,7 @@ add_static_target(expat expat_external libexpat.a) build_external(unbound DEPENDS openssl_external expat_external CONFIGURE_COMMAND ./configure ${cross_host} ${cross_extra} --prefix=${DEPS_DESTDIR} --disable-shared - --enable-static --with-libunbound-only --with-pic + --enable-static --with-libunbound-only --with-pic --disable-gost --$,enable,disable>-flto --with-ssl=${DEPS_DESTDIR} --with-libexpat=${DEPS_DESTDIR} "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" @@ -331,15 +356,33 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "^(Apple)?Clang$") else() message(FATAL_ERROR "don't know how to build boost with ${CMAKE_CXX_COMPILER_ID}") endif() -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam "using ${boost_toolset} : : ${deps_cxx} ;") + +if(IOS) + set(boost_arch_flags) + foreach(arch ${CMAKE_OSX_ARCHITECTURES}) + string(APPEND boost_arch_flags " -arch ${arch}") + endforeach() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam "using darwin : : ${deps_cxx} : + arm + iphone + \"-fPIC ${boost_arch_flags} ${CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET} -isysroot ${CMAKE_OSX_SYSROOT}\" + multi + ;") +else() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam "using ${boost_toolset} : : ${deps_cxx} ;") +endif() set(boost_patch_commands "") -if(APPLE AND BOOST_VERSION VERSION_LESS 1.74.0) +if(IOS) + set(boost_patch_commands PATCH_COMMAND patch -p1 -i ${PROJECT_SOURCE_DIR}/utils/build_scripts/boost-darwin-libtool-path.patch) +elseif(APPLE AND BOOST_VERSION VERSION_LESS 1.74.0) set(boost_patch_commands PATCH_COMMAND patch -p1 -d tools/build -i ${PROJECT_SOURCE_DIR}/utils/build_scripts/boostorg-build-pr560-macos-build-fix.patch) endif() set(boost_buildflags "cxxflags=-fPIC") -if(APPLE) +if(IOS) + set(boost_buildflags) +elseif(APPLE) set(boost_buildflags "cxxflags=-fPIC -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}" "cflags=-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") endif() @@ -376,12 +419,14 @@ set(Boost_VERSION ${BOOST_VERSION}) -build_external(sqlite3) +build_external(sqlite3 + BUILD_COMMAND true + INSTALL_COMMAND make install-includeHEADERS install-libLTLIBRARIES) add_static_target(sqlite3 sqlite3_external libsqlite3.a) -if (NOT (WIN32 OR ANDROID)) +if (NOT (WIN32 OR ANDROID OR IOS)) build_external(ncurses CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --without-debug --without-ada --without-cxx-binding --without-cxx --without-ticlib --without-tic --without-progs @@ -422,7 +467,7 @@ endif() -if(APPLE OR WIN32 OR ANDROID) +if(APPLE OR WIN32 OR ANDROID OR IOS) add_library(libudev INTERFACE) set(maybe_eudev "") else() @@ -439,7 +484,7 @@ endif() -if(NOT ANDROID) +if(NOT (ANDROID OR IOS)) build_external(libusb CONFIGURE_COMMAND autoreconf -ivf && ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --disable-shared --disable-udev --with-pic "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" @@ -454,7 +499,7 @@ endif() -if(ANDROID) +if(ANDROID OR IOS) set(HIDAPI_FOUND FALSE) else() if(CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -518,10 +563,17 @@ add_static_target(sodium sodium_external libsodium.a) if(ZMQ_VERSION VERSION_LESS 4.3.4 AND CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw) set(zmq_patch PATCH_COMMAND patch -p1 -i ${PROJECT_SOURCE_DIR}/utils/build_scripts/libzmq-mingw-closesocket.patch) endif() + +set(zmq_cross_host "${cross_host}") +if(IOS AND cross_host MATCHES "-ios$") + # zmq doesn't like "-ios" for the host, so replace it with -darwin + string(REGEX REPLACE "-ios$" "-darwin" zmq_cross_host ${cross_host}) +endif() + build_external(zmq DEPENDS sodium_external ${zmq_patch} - CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --enable-static --disable-shared + CONFIGURE_COMMAND ./configure ${zmq_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 "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=-fstack-protector ${deps_CFLAGS}" "CXXFLAGS=-fstack-protector ${deps_CXXFLAGS}" @@ -546,28 +598,77 @@ if(WIN32) set(curl_ssl_opts --without-ssl --with-schannel) elseif(APPLE) set(curl_ssl_opts --without-ssl --with-secure-transport) + if(IOS) + set(curl_LIBS "LDFLAGS=-L${DEPS_DESTDIR}/lib -isysroot ${CMAKE_OSX_SYSROOT}") + endif() else() set(curl_ssl_opts --with-ssl=${DEPS_DESTDIR}) set(curl_LIBS "LIBS=-pthread") endif() -build_external(curl - DEPENDS openssl_external zlib_external - CONFIGURE_COMMAND ./configure ${cross_host} ${cross_extra} --prefix=${DEPS_DESTDIR} --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 - "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ${curl_LIBS} - BUILD_BYPRODUCTS - ${DEPS_DESTDIR}/lib/libcurl.a - ${DEPS_DESTDIR}/include/curl/curl.h -) +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 + "CC=${deps_cc}" "CFLAGS=${deps_noarch_CFLAGS}${cflags_extra}" ${curl_LIBS} + 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) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 8156bc725..7a90f578e 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -34,7 +34,7 @@ # others. set(DEFAULT_WITH_MINIUPNPC ON) -if(ANDROID) +if(ANDROID OR IOS) set(DEFAULT_WITH_MINIUPNPC OFF) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bff425927..05c04a7d3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,19 +74,17 @@ add_subdirectory(net) add_subdirectory(mnemonics) add_subdirectory(wallet) add_subdirectory(cryptonote_protocol) +add_subdirectory(blockchain_db) +add_subdirectory(rpc) +add_subdirectory(serialization) +add_subdirectory(p2p) +add_subdirectory(daemonizer) +add_subdirectory(daemon) +add_subdirectory(simplewallet) -if(NOT IOS) - if (NOT BUILD_INTEGRATION) - add_subdirectory(gen_multisig) - add_subdirectory(blockchain_utilities) - endif() - add_subdirectory(blockchain_db) - add_subdirectory(rpc) - add_subdirectory(serialization) - add_subdirectory(p2p) - add_subdirectory(daemonizer) - add_subdirectory(daemon) - add_subdirectory(simplewallet) +if (NOT BUILD_INTEGRATION) + add_subdirectory(gen_multisig) + add_subdirectory(blockchain_utilities) endif() # We'll always add, but with EXCLUDE_FROM_ALL if you didn't ask for them (but this lets you do a diff --git a/src/crypto/cn_heavy_hash_hard_arm.cpp b/src/crypto/cn_heavy_hash_hard_arm.cpp index 020dae177..3347c34a2 100644 --- a/src/crypto/cn_heavy_hash_hard_arm.cpp +++ b/src/crypto/cn_heavy_hash_hard_arm.cpp @@ -38,13 +38,19 @@ extern "C" { #include "skein.h" } +#if !defined(__APPLE__) #include #include +#endif #include static bool hw_check_aes() { +#if !defined(__APPLE__) return (getauxval(AT_HWCAP) & HWCAP_AES) != 0; +#else + return true; +#endif } extern "C" const bool cpu_aes_enabled = hw_check_aes() && !force_software_aes(); diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt index dfbf2ce2c..d3170089b 100644 --- a/src/wallet/api/CMakeLists.txt +++ b/src/wallet/api/CMakeLists.txt @@ -63,8 +63,15 @@ install(FILES ${wallet_api_headers} DESTINATION include/wallet/api) function(combine_archives output_archive) + set(FULL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib${output_archive}.a) + set(output_archive_dummy_file ${CMAKE_CURRENT_BINARY_DIR}/${output_archive}.dummy.cpp) + add_custom_command(OUTPUT ${output_archive_dummy_file} + COMMAND touch ${output_archive_dummy_file} + DEPENDS ${ARGN}) + add_library(${output_archive} STATIC EXCLUDE_FROM_ALL ${output_archive_dummy_file}) + + if(NOT APPLE) set(mri_file ${CMAKE_CURRENT_BINARY_DIR}/${output_archive}.mri) - set(FULL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib${output_archive}.a) set(mri_content "create ${FULL_OUTPUT_PATH}\n") foreach(in_archive ${ARGN}) string(APPEND mri_content "addlib $\n") @@ -72,18 +79,20 @@ function(combine_archives output_archive) string(APPEND mri_content "save\nend\n") file(GENERATE OUTPUT ${mri_file} CONTENT "${mri_content}") - set(output_archive_dummy_file ${CMAKE_CURRENT_BINARY_DIR}/${output_archive}.dummy.cpp) - add_custom_command(OUTPUT ${output_archive_dummy_file} - COMMAND touch ${output_archive_dummy_file} - DEPENDS ${ARGN}) - - add_library(${output_archive} STATIC EXCLUDE_FROM_ALL ${output_archive_dummy_file}) add_custom_command(TARGET ${output_archive} POST_BUILD COMMAND ar -M < ${mri_file}) + else() + set(merge_libs) + foreach(in_archive ${ARGN}) + list(APPEND merge_libs $) + endforeach() + add_custom_command(TARGET ${output_archive} + POST_BUILD + COMMAND /usr/bin/libtool -static -o ${FULL_OUTPUT_PATH} ${merge_libs}) + endif() endfunction(combine_archives) -# build and install libwallet_merged only if we building for GUI if (STATIC AND BUILD_STATIC_DEPS) combine_archives(wallet_merged wallet_api diff --git a/utils/build_scripts/boost-darwin-libtool-path.patch b/utils/build_scripts/boost-darwin-libtool-path.patch new file mode 100644 index 000000000..727b5e735 --- /dev/null +++ b/utils/build_scripts/boost-darwin-libtool-path.patch @@ -0,0 +1,11 @@ +--- a/tools/build/src/tools/darwin.jam 2020-10-29 23:37:52.000000000 -0300 ++++ b/tools/build/src/tools/darwin.jam 2020-10-29 23:37:43.000000000 -0300 +@@ -192,7 +192,7 @@ + # archives in darwin is complicated. + local archiver = + [ common.get-invocation-command darwin +- : libtool : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; ++ : /usr/bin/libtool : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; + flags darwin.archive .LIBTOOL $(condition) : $(archiver[1]) ; + if $(.debug-configuration) + {