From bb40433612014705d643fea3e4042837e445515f Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Sat, 24 Oct 2020 15:29:47 -0300 Subject: [PATCH] Android build infrastructure updates - Various static deps updated needed for properly cross-compiling libraries for android. - disable LTO because it doesn't work reliably with the android NDK. - allow building without miniupnpc, and default to not building it under android. - make sure we build translation tools on the native arch when cross-compiling for android. - don't build ncurses, libusb, hidapi when doing an android build --- CMakeLists.txt | 2 +- cmake/StaticBuild.cmake | 138 ++++++++++++++++++++++++------------ external/CMakeLists.txt | 16 ++++- src/p2p/net_node.inl | 12 ++++ translations/CMakeLists.txt | 13 ++++ 5 files changed, 131 insertions(+), 50 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfcc43128..aad2080b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,7 +148,7 @@ endif() cmake_policy(SET CMP0069 NEW) SET(CMAKE_POLICY_DEFAULT_CMP0069 NEW) -if(CMAKE_BUILD_TYPE STREQUAL Release AND NOT MINGW) +if(CMAKE_BUILD_TYPE STREQUAL Release AND NOT MINGW AND NOT ANDROID) set(USE_LTO_DEFAULT ON) else() set(USE_LTO_DEFAULT OFF) diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake index c14991526..703eaa348 100644 --- a/cmake/StaticBuild.cmake +++ b/cmake/StaticBuild.cmake @@ -125,6 +125,29 @@ file(MAKE_DIRECTORY ${DEPS_DESTDIR}/include) set(deps_cc "${CMAKE_C_COMPILER}") set(deps_cxx "${CMAKE_CXX_COMPILER}") +if (ANDROID) + if(NOT ANDROID_TOOLCHAIN_NAME) + message(FATAL_ERROR "ANDROID_TOOLCHAIN_NAME not set; did you run with the proper android toolchain options?") + endif() + if(CMAKE_ANDROID_ARCH_ABI MATCHES x86_64) + set(android_clang x86_64-linux-android${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine x86_64) + elseif(CMAKE_ANDROID_ARCH_ABI MATCHES x86) + set(android_clang i686-linux-android${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine i686) + elseif(CMAKE_ANDROID_ARCH_ABI MATCHES armeabi-v7a) + set(android_clang armv7a-linux-androideabi${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine armv7) + elseif(CMAKE_ANDROID_ARCH_ABI MATCHES arm64-v8a) + set(android_clang aarch64-linux-android${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine aarch64) + else() + message(FATAL_ERROR "Don't know how to build for android arch abi ${CMAKE_ANDROID_ARCH_ABI}") + endif() + set(deps_cc "${ANDROID_TOOLCHAIN_ROOT}/bin/${android_clang}") + set(deps_cxx "${deps_cc}++") +endif() + if(CMAKE_C_COMPILER_LAUNCHER) set(deps_cc "${CMAKE_C_COMPILER_LAUNCHER} ${deps_cc}") endif() @@ -157,14 +180,19 @@ else() endif() set(cross_host "") -set(cross_rc "") -if(CMAKE_CROSSCOMPILING) +set(cross_extra "") +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_rc "WINDRES=${CMAKE_RC_COMPILER}") + set(cross_extra "WINDRES=${CMAKE_RC_COMPILER}") endif() endif() + + set(deps_CFLAGS "-O2 ${flto}") set(deps_CXXFLAGS "-O2 ${flto}") @@ -180,7 +208,7 @@ endif() 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}) + "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" ${cross_extra}) 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) @@ -215,7 +243,7 @@ endfunction() build_external(zlib - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ./configure --prefix=${DEPS_DESTDIR} --static + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ${cross_extra} ./configure --prefix=${DEPS_DESTDIR} --static BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/libz.a ${DEPS_DESTDIR}/include/zlib.h @@ -230,11 +258,14 @@ if(CMAKE_CROSSCOMPILING) set(openssl_system_env SYSTEM=MINGW64 RC=${CMAKE_RC_COMPILER}) elseif(ARCH_TRIPLET STREQUAL i686-w64-mingw32) set(openssl_system_env SYSTEM=MINGW64 RC=${CMAKE_RC_COMPILER}) + elseif(ANDROID) + set(openssl_system_env SYSTEM=Linux MACHINE=${openssl_machine} ${cross_extra}) + set(openssl_extra_opts no-asm) endif() endif() build_external(openssl CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${deps_cc} ${openssl_system_env} ./config - --prefix=${DEPS_DESTDIR} no-shared no-capieng no-dso no-dtls1 no-ec_nistp_64_gcc_128 no-gost + --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}" INSTALL_COMMAND make install_sw @@ -259,7 +290,7 @@ 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 + CONFIGURE_COMMAND ./configure ${cross_host} ${cross_extra} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-libunbound-only --with-pic --$,enable,disable>-flto --with-ssl=${DEPS_DESTDIR} --with-libexpat=${DEPS_DESTDIR} @@ -348,7 +379,7 @@ add_static_target(sqlite3 sqlite3_external libsqlite3.a) -if (NOT WIN32) +if (NOT (WIN32 OR ANDROID)) 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 @@ -389,7 +420,7 @@ endif() -if(APPLE OR WIN32) +if(APPLE OR WIN32 OR ANDROID) add_library(libudev INTERFACE) set(maybe_eudev "") else() @@ -406,53 +437,65 @@ endif() -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}" - BUILD_BYPRODUCTS - ${DEPS_DESTDIR}/lib/libusb-1.0.a - ${DEPS_DESTDIR}/include/libusb-1.0 - ${DEPS_DESTDIR}/include/libusb-1.0/libusb.h -) -add_static_target(libusb_vendor libusb_external libusb-1.0.a) -set_target_properties(libusb_vendor PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${DEPS_DESTDIR}/include/libusb-1.0) +if(NOT ANDROID) + 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}" + BUILD_BYPRODUCTS + ${DEPS_DESTDIR}/lib/libusb-1.0.a + ${DEPS_DESTDIR}/include/libusb-1.0 + ${DEPS_DESTDIR}/include/libusb-1.0/libusb.h + ) + add_static_target(libusb_vendor libusb_external libusb-1.0.a) + set_target_properties(libusb_vendor PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${DEPS_DESTDIR}/include/libusb-1.0) +endif() -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(hidapi_libusb_lib libhidapi-libusb.a) - set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi-libusb.a ${DEPS_DESTDIR}/lib/libhidapi-hidraw.a) +if(ANDROID) + set(HIDAPI_FOUND FALSE) else() - set(hidapi_libusb_lib libhidapi.a) - set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi.a) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(hidapi_libusb_lib libhidapi-libusb.a) + set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi-libusb.a ${DEPS_DESTDIR}/lib/libhidapi-hidraw.a) + else() + set(hidapi_libusb_lib libhidapi.a) + set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi.a) + endif() + build_external(hidapi + DEPENDS ${maybe_eudev} libusb_external + CONFIGURE_COMMAND autoreconf -ivf && ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-pic + "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" + ${cross_extra} + "libudev_CFLAGS=-I${DEPS_DESTDIR}/include" "libudev_LIBS=-L${DEPS_DESTDIR}/lib -ludev" + "libusb_CFLAGS=-I${DEPS_DESTDIR}/include/libusb-1.0" "libusb_LIBS=-L${DEPS_DESTDIR}/lib -lusb-1.0" + BUILD_BYPRODUCTS + ${hidapi_lib_byproducts} + ${DEPS_DESTDIR}/include/hidapi + ${DEPS_DESTDIR}/include/hidapi/hidapi.h + ) + set(HIDAPI_FOUND TRUE) + add_static_target(hidapi_libusb hidapi_external ${hidapi_libusb_lib}) + set(hidapi_links "libusb_vendor;libudev") + if(WIN32) + list(APPEND hidapi_links setupapi) + endif() + set_target_properties(hidapi_libusb PROPERTIES + INTERFACE_LINK_LIBRARIES "${hidapi_links}" + INTERFACE_COMPILE_DEFINITIONS HAVE_HIDAPI) endif() -build_external(hidapi - DEPENDS ${maybe_eudev} libusb_external - CONFIGURE_COMMAND autoreconf -ivf && ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-pic - "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" - "libudev_CFLAGS=-I${DEPS_DESTDIR}/include" "libudev_LIBS=-L${DEPS_DESTDIR}/lib -ludev" - "libusb_CFLAGS=-I${DEPS_DESTDIR}/include/libusb-1.0" "libusb_LIBS=-L${DEPS_DESTDIR}/lib -lusb-1.0" - BUILD_BYPRODUCTS - ${hidapi_lib_byproducts} - ${DEPS_DESTDIR}/include/hidapi - ${DEPS_DESTDIR}/include/hidapi/hidapi.h -) -set(HIDAPI_FOUND TRUE) -add_static_target(hidapi_libusb hidapi_external ${hidapi_libusb_lib}) -set(hidapi_links "libusb_vendor;libudev") -if(WIN32) - list(APPEND hidapi_links setupapi) + + + +set(protobuf_extra "") +if(ANDROID) + set(protobuf_extra "LDFLAGS=-llog") endif() -set_target_properties(hidapi_libusb PROPERTIES - INTERFACE_LINK_LIBRARIES "${hidapi_links}" - INTERFACE_COMPILE_DEFINITIONS HAVE_HIDAPI) - - - build_external(protobuf 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_extra} ${protobuf_extra} "CPP=${deps_cc} -E" "CXXCPP=${deps_cxx} -E" "CC_FOR_BUILD=${deps_cc}" "CXX_FOR_BUILD=${deps_cxx}" # Thanks Google for making people hunt for undocumented magic variables BUILD_BYPRODUCTS @@ -480,6 +523,7 @@ build_external(zmq --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}" + ${cross_extra} "sodium_CFLAGS=-I${DEPS_DESTDIR}/include" "sodium_LIBS=-L${DEPS_DESTDIR}/lib -lsodium" ) add_static_target(libzmq zmq_external libzmq.a) @@ -507,7 +551,7 @@ endif() build_external(curl DEPENDS openssl_external zlib_external - CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared + 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 diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 4177eeb05..85a8ec137 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -33,14 +33,26 @@ # ...except for FreeBSD, because FreeBSD is a special case that doesn't play well with # others. +set(DEFAULT_WITH_MINIUPNPC ON) +if(ANDROID) + set(DEFAULT_WITH_MINIUPNPC OFF) +endif() + +option(WITH_MINIUPNPC "Enable miniupnpc support for IGD NAT hole punching" ${DEFAULT_WITH_MINIUPNPC}) + if(NOT STATIC AND NOT BUILD_STATIC_DEPS) find_package(PkgConfig REQUIRED) - pkg_check_modules(MINIUPNPC miniupnpc>=2.1) + if(WITH_MINIUPNPC) + pkg_check_modules(MINIUPNPC miniupnpc>=2.1) + endif() pkg_check_modules(UNBOUND libunbound) pkg_check_modules(LOKIMQ liblokimq>=1.2) endif() -if(MINIUPNPC_FOUND) +if(NOT WITH_MINIUPNPC) + message(STATUS "miniupnpc support disabled") + target_compile_definitions(miniupnpc INTERFACE WITHOUT_MINIUPNPC) +elseif(MINIUPNPC_FOUND) message(STATUS "Found miniupnpc") link_dep_libs(miniupnpc INTERFACE "${MINIUPNPC_LIBRARY_DIRS}" ${MINIUPNPC_LIBRARIES}) target_include_directories(miniupnpc INTERFACE ${MINIUPNPC_INCLUDE_DIRS}) diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index f02c48733..18dd0a05f 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -57,9 +57,11 @@ #include "cryptonote_core/cryptonote_core.h" #include "net/parse.h" +#ifndef WITHOUT_MINIUPNPC #include #include #include +#endif #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "net.p2p" @@ -2654,6 +2656,10 @@ namespace nodetool template void node_server::add_upnp_port_mapping_impl(uint32_t port, bool ipv6) // if ipv6 false, do ipv4 { +#ifdef WITHOUT_MINIUPNPC + (void) port; + (void) ipv6; +#else std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)"; MDEBUG("Attempting to add IGD port mapping " << ipversion << "."); int result; @@ -2698,6 +2704,7 @@ namespace nodetool } else { MINFO("No IGD was found."); } +#endif } template @@ -2723,6 +2730,10 @@ namespace nodetool template void node_server::delete_upnp_port_mapping_impl(uint32_t port, bool ipv6) { +#ifdef WITHOUT_MINIUPNPC + (void) port; + (void) ipv6; +#else std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)"; MDEBUG("Attempting to delete IGD port mapping " << ipversion << "."); int result; @@ -2763,6 +2774,7 @@ namespace nodetool } else { MINFO("No IGD was found."); } +#endif } template diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt index ff31ed91c..b43391622 100644 --- a/translations/CMakeLists.txt +++ b/translations/CMakeLists.txt @@ -26,6 +26,19 @@ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +if (ANDROID) + # Override the stuff (locally, inside this subdir) because we want to find the host system Qt5 to + # build the translation files. + set(CMAKE_FIND_ROOT_PATH "") + # This might be wrong, but cmake gives us no easy way to find this, so for now we only support + # doing the android builds with translations on amd64 linux + set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(ANDROID_PLATFORM FALSE) +endif() find_package(Qt5 QUIET COMPONENTS Core LinguistTools) if(NOT Qt5_FOUND OR NOT Qt5LinguistTools_FOUND) set(qm_files "")