为低于6.0(API级别23)的Android版本构建libcurl失败

时间:2019-06-06 16:38:12

标签: android curl android-ndk libcurl

我正在尝试在Windows上使用Clang来为Android构建libcurl,但是在为低于23(Android 6.0)的Android API级别构建时遇到链接器问题。链接器抱怨无法解析符号,并显示以下输出:

undefined reference to 'stdin'
undefined reference to 'stdout'
undefined reference to 'stdin'
undefined reference to 'stdout'
undefined reference to 'stdout'
undefined reference to 'stderr'
undefined reference to 'stdout'
undefined reference to 'stdin'
undefined reference to 'stderr'

在后台,我使用Visual Studio 2019和“带有C ++的移动开发”工作负载来构建libcurl。但是,实际上这并不重要,因为Visual Studio最终只会调用Android NDK r16b提供的工具。 Visual Studio调用的所有命令都清晰可见。

所使用的链接器命令如下所示(为提高可读性而进行了格式化):

C:\Microsoft\AndroidNDK64\android-ndk-r16b\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe
-fdiagnostics-format=msvc
-o"obj\Debug\ARM\libcurl.so"
-Wl,-soname="libcurl.so"
-Wl,-rpath-link="C:\Microsoft\AndroidNDK64\android-ndk-r16b\platforms\android-15\arch-arm\usr\lib"
-Wl,-L"C:\Microsoft\AndroidNDK64\android-ndk-r16b\platforms\android-15\arch-arm\usr\lib"
-Wl,-L"C:\Microsoft\AndroidNDK64\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\armv7-a"
-Wl,-L"C:\Microsoft\AndroidNDK64\android-ndk-r16b\sources\cxx-stl\llvm-libc++\libs\armeabi-v7a"
-Wl,--no-undefined
-gcc-toolchain "C:\Microsoft\AndroidNDK64\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64"
-target "armv7-none-linux-androideabi"
--sysroot="C:\Microsoft\AndroidNDK64\android-ndk-r16b\platforms\android-15\arch-arm"
-Wl,-z,relro
-Wl,-z,now
-Wl,-z,noexecstack
-shared obj\Debug\ARM\cleartext.o
obj\Debug\ARM\cram.o
obj\Debug\ARM\digest.o
obj\Debug\ARM\digest_sspi.o
obj\Debug\ARM\krb5_gssapi.o
obj\Debug\ARM\krb5_sspi.o
obj\Debug\ARM\ntlm.o
obj\Debug\ARM\ntlm_sspi.o
obj\Debug\ARM\oauth2.o
obj\Debug\ARM\spnego_gssapi.o
obj\Debug\ARM\spnego_sspi.o
obj\Debug\ARM\vauth.o
obj\Debug\ARM\cyassl.o
obj\Debug\ARM\gskit.o
obj\Debug\ARM\gtls.o
obj\Debug\ARM\mbedtls.o
obj\Debug\ARM\mesalink.o
obj\Debug\ARM\nss.o
obj\Debug\ARM\openssl.o
obj\Debug\ARM\polarssl.o
obj\Debug\ARM\polarssl_threadlock.o
obj\Debug\ARM\schannel.o
obj\Debug\ARM\schannel_verify.o
obj\Debug\ARM\sectransp.o
obj\Debug\ARM\vtls.o
obj\Debug\ARM\altsvc.o
obj\Debug\ARM\amigaos.o
obj\Debug\ARM\asyn-ares.o
obj\Debug\ARM\asyn-thread.o
obj\Debug\ARM\base64.o
obj\Debug\ARM\conncache.o
obj\Debug\ARM\connect.o
obj\Debug\ARM\content_encoding.o
obj\Debug\ARM\cookie.o
obj\Debug\ARM\curl_addrinfo.o
obj\Debug\ARM\curl_ctype.o
obj\Debug\ARM\curl_des.o
obj\Debug\ARM\curl_endian.o
obj\Debug\ARM\curl_fnmatch.o
obj\Debug\ARM\curl_get_line.o
obj\Debug\ARM\curl_gethostname.o
obj\Debug\ARM\curl_gssapi.o
obj\Debug\ARM\curl_memrchr.o
obj\Debug\ARM\curl_multibyte.o
obj\Debug\ARM\curl_ntlm_core.o
obj\Debug\ARM\curl_ntlm_wb.o
obj\Debug\ARM\curl_path.o
obj\Debug\ARM\curl_range.o
obj\Debug\ARM\curl_rtmp.o
obj\Debug\ARM\curl_sasl.o
obj\Debug\ARM\curl_sspi.o
obj\Debug\ARM\curl_threads.o
obj\Debug\ARM\dict.o
obj\Debug\ARM\doh.o
obj\Debug\ARM\dotdot.o
obj\Debug\ARM\easy.o
obj\Debug\ARM\escape.o
obj\Debug\ARM\file.o
obj\Debug\ARM\fileinfo.o
obj\Debug\ARM\formdata.o
obj\Debug\ARM\ftp.o
obj\Debug\ARM\ftplistparser.o
obj\Debug\ARM\getenv.o
obj\Debug\ARM\getinfo.o
obj\Debug\ARM\gopher.o
obj\Debug\ARM\hash.o
obj\Debug\ARM\hmac.o
obj\Debug\ARM\hostasyn.o
obj\Debug\ARM\hostcheck.o
obj\Debug\ARM\hostip.o
obj\Debug\ARM\hostip4.o
obj\Debug\ARM\hostip6.o
obj\Debug\ARM\hostsyn.o
obj\Debug\ARM\http.o
obj\Debug\ARM\http_chunks.o
obj\Debug\ARM\http_digest.o
obj\Debug\ARM\http_negotiate.o
obj\Debug\ARM\http_ntlm.o
obj\Debug\ARM\http_proxy.o
obj\Debug\ARM\http2.o
obj\Debug\ARM\idn_win32.o
obj\Debug\ARM\if2ip.o
obj\Debug\ARM\imap.o
obj\Debug\ARM\inet_ntop.o
obj\Debug\ARM\inet_pton.o
obj\Debug\ARM\krb5.o
obj\Debug\ARM\ldap.o
obj\Debug\ARM\llist.o
obj\Debug\ARM\md4.o
obj\Debug\ARM\md5.o
obj\Debug\ARM\memdebug.o
obj\Debug\ARM\mime.o
obj\Debug\ARM\mprintf.o
obj\Debug\ARM\multi.o
obj\Debug\ARM\netrc.o
obj\Debug\ARM\non-ascii.o
obj\Debug\ARM\nonblock.o
obj\Debug\ARM\nwlib.o
obj\Debug\ARM\nwos.o
obj\Debug\ARM\openldap.o
obj\Debug\ARM\parsedate.o
obj\Debug\ARM\pingpong.o
obj\Debug\ARM\pop3.o
obj\Debug\ARM\progress.o
obj\Debug\ARM\psl.o
obj\Debug\ARM\rand.o
obj\Debug\ARM\rtsp.o
obj\Debug\ARM\security.o
obj\Debug\ARM\select.o
obj\Debug\ARM\sendf.o
obj\Debug\ARM\setopt.o
obj\Debug\ARM\sha256.o
obj\Debug\ARM\share.o
obj\Debug\ARM\slist.o
obj\Debug\ARM\smb.o
obj\Debug\ARM\smtp.o
obj\Debug\ARM\socks.o
obj\Debug\ARM\socks_gssapi.o
obj\Debug\ARM\socks_sspi.o
obj\Debug\ARM\speedcheck.o
obj\Debug\ARM\splay.o
obj\Debug\ARM\ssh.o
obj\Debug\ARM\ssh-libssh.o
obj\Debug\ARM\strcase.o
obj\Debug\ARM\strdup.o
obj\Debug\ARM\strerror.o
obj\Debug\ARM\strtok.o
obj\Debug\ARM\strtoofft.o
obj\Debug\ARM\system_win32.o
obj\Debug\ARM\telnet.o
obj\Debug\ARM\tftp.o
obj\Debug\ARM\timeval.o
obj\Debug\ARM\transfer.o
obj\Debug\ARM\url.o
obj\Debug\ARM\urlapi.o
obj\Debug\ARM\version.o
obj\Debug\ARM\warnless.o
obj\Debug\ARM\wildcard.o
obj\Debug\ARM\x509asn1.o
-landroid_support
-lc++_shared
-lc++abi
-llog
-landroid

通过上述命令链接的目标文件都使用相同的Clang开关进行编译。一个示例如下所示:

C:\Microsoft\AndroidNDK64\android-ndk-r16b\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe
-c
-fdiagnostics-format=msvc
-gcc-toolchain "C:\Microsoft\AndroidNDK64\android-ndk-r16b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64"
-target "armv7-none-linux-androideabi"
--sysroot="C:\Microsoft\AndroidNDK64\android-ndk-r16b\sysroot"
-isystem "C:\Microsoft\AndroidNDK64\android-ndk-r16b\sysroot\usr\include\arm-linux-androideabi"
-I "C:\Microsoft\AndroidNDK64\android-ndk-r16b\sources\cxx-stl\llvm-libc++\include"
-I "C:\Microsoft\AndroidNDK64\android-ndk-r16b\sources\cxx-stl\llvm-libc++abi\include"
-I "C:\Microsoft\AndroidNDK64\android-ndk-r16b\sysroot\usr\include"
-I "C:\Microsoft\AndroidNDK64\android-ndk-r16b\sysroot\usr\include\arm-linux-androideabi"
-I "C:\Microsoft\AndroidNDK64\android-ndk-r16b\sources\android\support\include"
-I D:\MyProject\libcurl_src\
-I D:\MyProject\libcurl_src\curl\lib
-I D:\MyProject\libcurl_src\curl\include
-I "C:\Microsoft\AndroidNDK64\android-ndk-r16b\toolchains\llvm\prebuilt\windows-x86_64\lib64\clang\5.0.300080\include"
-g2
-gdwarf-2
-o "obj\Debug\ARM\altsvc.o"
-Wall
-O0
-fno-strict-aliasing
-mthumb
-fno-omit-frame-pointer
-fexceptions
-mfloat-abi=softfp
-fstack-protector
-fpic
-fno-short-enums
-D HAVE_CONFIG_H
-x c D:\MyProject\libcurl_src\curl\lib\altsvc.c

一旦我将提供给链接器的路径从\android-15\更改为\android-23\,它就会成功链接。但是,我需要支持6.0之前的Android版本,因此不能解决该问题。

我正在使用的curl_config.h文件如下所示:

#define BUILDING_LIBCURL 1
#define CURL_STATICLIB 1
#if defined(__ANDROID__)
#define CURL_CA_PATH "/system/etc/security/cacerts"
#endif
#define CURL_DISABLE_DICT 1
#define CURL_DISABLE_FILE 1
#define CURL_DISABLE_FTP 1
#define CURL_DISABLE_GOPHER 1
#define CURL_DISABLE_IMAP 1
#define CURL_DISABLE_LDAP 1
#define CURL_DISABLE_LDAPS 1
#define CURL_DISABLE_POP3 1
#define CURL_DISABLE_RTSP 1
#define CURL_DISABLE_SMB 1
#define CURL_DISABLE_SMTP 1
#define CURL_DISABLE_TELNET 1
#define CURL_DISABLE_TFTP 1
#define CURL_EXTERN_SYMBOL __attribute__((visibility("default")))
#define CURL_SA_FAMILY_T sa_family_t
#define ENABLE_IPV6 1
#define GETHOSTNAME_TYPE_ARG2 size_t
#define HAVE_ALARM 1
#define HAVE_ALLOCA_H 1
#define HAVE_ARPA_INET_H 1
#define HAVE_ARPA_TFTP_H 1
#define HAVE_ASSERT_H 1
#define HAVE_BASENAME 1
#define HAVE_BOOL_T 1
#define HAVE_BUILTIN_AVAILABLE 1
#define HAVE_CLOCK_GETTIME_MONOTONIC 1
#define HAVE_CONNECT 1
#define HAVE_DECL_GETPWUID_R 1
#define HAVE_DLFCN_H 1
#define HAVE_ERRNO_H 1
#define HAVE_ERR_H 1
#define HAVE_FCNTL 1
#define HAVE_FCNTL_H 1
#define HAVE_FCNTL_O_NONBLOCK 1
#define HAVE_FNMATCH 1
#define HAVE_FREEADDRINFO 1
#define HAVE_FSETXATTR 1
#define HAVE_FSETXATTR_5 1
#define HAVE_FTRUNCATE 1
#define HAVE_GAI_STRERROR 1
#define HAVE_GETADDRINFO 1
#define HAVE_GETADDRINFO_THREADSAFE 1
#define HAVE_GETEUID 1
#define HAVE_GETHOSTBYADDR 1
#define HAVE_GETHOSTBYADDR_R 1
#define HAVE_GETHOSTBYADDR_R_8 1
#define HAVE_GETHOSTBYNAME 1
#define HAVE_GETHOSTBYNAME_R 1
#define HAVE_GETHOSTBYNAME_R_6 1
#define HAVE_GETHOSTNAME 1
#define HAVE_GETPEERNAME 1
#define HAVE_GETPPID 1
#define HAVE_GETPWUID 1
#define HAVE_GETPWUID_R 1
#define HAVE_GETRLIMIT 1
#define HAVE_GETSOCKNAME 1
#define HAVE_GETTIMEOFDAY 1
#define HAVE_GMTIME_R 1
#define HAVE_IFADDRS_H 1
#define HAVE_IF_NAMETOINDEX 1
#define HAVE_INET_NTOP 1
#define HAVE_INET_PTON 1
#define HAVE_INTTYPES_H 1
#define HAVE_IOCTL 1
#define HAVE_IOCTL_FIONBIO 1
#define HAVE_IOCTL_SIOCGIFADDR 1
#define HAVE_LIBGEN_H 1
#define HAVE_LIBSSL 1
#if defined(__ANDROID__)
#define HAVE_LINUX_TCP_H 1
#endif
#define HAVE_LL 1
#define HAVE_LOCALE_H 1
#define HAVE_LOCALTIME_R 1
#define HAVE_LONGLONG 1
#define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1
#if defined(__ANDROID__)
#define HAVE_MEMRCHR 1
#endif
#if defined(__ANDROID__)
#define HAVE_MSG_NOSIGNAL 1
#endif
#define HAVE_NETDB_H 1
#define HAVE_NETINET_IN_H 1
#define HAVE_NETINET_TCP_H 1
#define HAVE_NET_IF_H 1
#define HAVE_PIPE 1
#define HAVE_POLL 1
#define HAVE_POLL_FINE 1
#define HAVE_POLL_H 1
#define HAVE_POSIX_STRERROR_R 1
#define HAVE_PTHREAD_H 1
#define HAVE_PWD_H 1
#define HAVE_RECV 1
#define HAVE_SELECT 1
#define HAVE_SEND 1
#define HAVE_SETJMP_H 1
#define HAVE_SETLOCALE 1
#define HAVE_SETRLIMIT 1
#define HAVE_SETSOCKOPT 1
#define HAVE_SIGACTION 1
#define HAVE_SIGINTERRUPT 1
#define HAVE_SIGNAL 1
#define HAVE_SIGNAL_H 1
#define HAVE_SIG_ATOMIC_T 1
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
#define HAVE_SOCKET 1
#define HAVE_SOCKETPAIR 1
#define HAVE_STDBOOL_H 1
#define HAVE_STDINT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRCASECMP 1
#define HAVE_STRDUP 1
#define HAVE_STRERROR_R 1
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
#define HAVE_STRNCASECMP 1
#define HAVE_STRSTR 1
#define HAVE_STRTOK_R 1
#define HAVE_STRTOLL 1
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
#define HAVE_STRUCT_TIMEVAL 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_POLL_H 1
#define HAVE_SYS_RESOURCE_H 1
#define HAVE_SYS_SELECT_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_UIO_H 1
#define HAVE_SYS_UN_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_SYS_XATTR_H 1
#define HAVE_TERMIOS_H 1
#define HAVE_TERMIO_H 1
#define HAVE_TIME_H 1
#define HAVE_UNISTD_H 1
#define HAVE_UTIME 1
#define HAVE_UTIMES 1
#define HAVE_UTIME_H 1
#define HAVE_VARIADIC_MACROS_C99 1
#define HAVE_VARIADIC_MACROS_GCC 1
#define HAVE_WRITEV 1
#define LT_OBJDIR ".libs/"
#define OS "arm-unknown-linux-android"
#define PACKAGE "curl"
#define PACKAGE_NAME "curl"
#define PACKAGE_STRING "curl -"
#define PACKAGE_TARNAME "curl"
#define PACKAGE_URL ""
#define PACKAGE_VERSION "-"
#define RECV_TYPE_ARG1 int
#define RECV_TYPE_ARG2 void *
#define RECV_TYPE_ARG3 size_t
#define RECV_TYPE_ARG4 int
#define RECV_TYPE_RETV ssize_t
#define RETSIGTYPE void
#define SELECT_QUAL_ARG5 
#define SELECT_TYPE_ARG1 int
#define SELECT_TYPE_ARG234 fd_set *
#define SELECT_TYPE_ARG5 struct timeval *
#define SELECT_TYPE_RETV ssize_t
#define SEND_QUAL_ARG2 const
#define SEND_TYPE_ARG1 int
#define SEND_TYPE_ARG2 void *
#define SEND_TYPE_ARG3 size_t
#define SEND_TYPE_ARG4 int
#define SEND_TYPE_RETV ssize_t
#define SIZEOF_CURL_OFF_T 8
#define SIZEOF_INT 4
#define SIZEOF_LONG 4
#define SIZEOF_LONG_LONG 8
#define SIZEOF_OFF_T 4
#define SIZEOF_SHORT 2
#define SIZEOF_SIZE_T 4
#define SIZEOF_TIME_T 4
#define STDC_HEADERS 1
#define STRERROR_R_TYPE_ARG3 size_t
#define TIME_WITH_SYS_TIME 1
#if defined(__ANDROID__)
//#define USE_MBEDTLS 1
#endif
#if defined(_WIN32)
#define USE_SCHANNEL 1
#endif
#if defined(__APPLE__)
#define USE_SECTRANSP 1
#endif
#define USE_THREADS_POSIX 1
#define USE_UNIX_SOCKETS 1
#define VERSION "-"
#ifndef _ALL_SOURCE
#endif
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
#define _FILE_OFFSET_BITS 64

有人暗示我可能会遇到这个问题吗?

我不确定libcurl为何实际上实际上需要stdin / stdout / stderr。对于curl可执行文件来说很有意义,但是也许我很幸运,并且可以以某种方式从libcurl中删除相应的功能。有任何提示吗?

0 个答案:

没有答案