Don't link directly to libcurl.

Lots of Linux distros have different names (libcurl-gnutls.so vs etc), and
version the symbols (curl_global_init@@CURL_LIBSSL_3), so it's more compatible
to just dlsym the basic entry points we need and just demand that libcurl is
installed at all.

Alternately: we'll use our own libcurl build, but we'll probably have to dump
SSL support to make this sane to do.
This commit is contained in:
Ryan C. Gordon 2017-05-30 20:15:59 -04:00
parent b892bcfdbc
commit f518f75149
2 changed files with 59 additions and 2 deletions

View File

@ -1588,7 +1588,7 @@ $(B)/autoupdater/%.o: $(AUTOUPDATERSRCDIR)/%.c
$(B)/$(AUTOUPDATER_BIN): $(Q3AUTOUPDATEROBJ) $(B)/$(AUTOUPDATER_BIN): $(Q3AUTOUPDATEROBJ)
$(echo_cmd) "AUTOUPDATER_LD $@" $(echo_cmd) "AUTOUPDATER_LD $@"
$(Q)$(CC) $(LDFLAGS) -o $@ $(Q3AUTOUPDATEROBJ) $(CURL_LIBS) $(Q)$(CC) $(LDFLAGS) -o $@ $(Q3AUTOUPDATEROBJ) $(LIBS)
############################################################################# #############################################################################

View File

@ -151,8 +151,61 @@ static void restoreRollbacks(void)
} }
} }
static void die(const char *why) NEVER_RETURNS; static void die(const char *why) NEVER_RETURNS;
#ifndef _WIN32 /* hooray for Unix linker hostility! */
#undef curl_easy_setopt
#include <dlfcn.h>
typedef void (*CURLFN_curl_easy_cleanup)(CURL *curl);
typedef CURL *(*CURLFN_curl_easy_init)(void);
typedef CURLcode (*CURLFN_curl_easy_setopt)(CURL *curl, CURLoption option, ...);
typedef CURLcode (*CURLFN_curl_easy_perform)(CURL *curl);
typedef CURLcode (*CURLFN_curl_global_init)(long flags);
typedef void (*CURLFN_curl_global_cleanup)(void);
static CURLFN_curl_easy_cleanup CURL_curl_easy_cleanup;
static CURLFN_curl_easy_init CURL_curl_easy_init;
static CURLFN_curl_easy_setopt CURL_curl_easy_setopt;
static CURLFN_curl_easy_perform CURL_curl_easy_perform;
static CURLFN_curl_global_init CURL_curl_global_init;
static CURLFN_curl_global_cleanup CURL_curl_global_cleanup;
static void load_libcurl(void)
{
#ifdef __APPLE__
const char *libname = "libcurl.4.dylib";
#else
const char *libname = "libcurl.so.4";
#endif
void *handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
infof("dlopen(\"%s\") failed: %s", libname, dlerror());
die("Failed to load libcurl library");
}
#define LOADCURLSYM(fn) \
if ((CURL_##fn = (CURLFN_##fn) dlsym(handle, #fn)) == NULL) { \
die("Failed to load libcurl symbol '" #fn "'"); \
}
LOADCURLSYM(curl_easy_cleanup);
LOADCURLSYM(curl_easy_init);
LOADCURLSYM(curl_easy_setopt);
LOADCURLSYM(curl_easy_perform);
LOADCURLSYM(curl_global_init);
LOADCURLSYM(curl_global_cleanup);
}
#define curl_easy_cleanup CURL_curl_easy_cleanup
#define curl_easy_init CURL_curl_easy_init
#define curl_easy_setopt CURL_curl_easy_setopt
#define curl_easy_perform CURL_curl_easy_perform
#define curl_global_init CURL_curl_global_init
#define curl_global_cleanup CURL_curl_global_cleanup
#endif
static void die(const char *why) static void die(const char *why)
{ {
infof("FAILURE: %s", why); infof("FAILURE: %s", why);
@ -696,6 +749,10 @@ int main(int argc, char **argv)
upgradeSelfAndRestart(argv[0]); upgradeSelfAndRestart(argv[0]);
} }
#ifndef _WIN32
load_libcurl();
#endif
if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) {
die("curl_global_init() failed!"); die("curl_global_init() failed!");
} }