drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.43k stars 1.1k forks source link

vcpkg: Windows static build fails #510

Open haraldegger opened 4 years ago

haraldegger commented 4 years ago

Describe the bug When building under Windows 10 x64 with Visual Studio 2019 everything works fine when building with dynamic linking as indicated in the instructions: vcpkg.exe install drogon:x64-windows When building instead with static linking the process fails because it cannot find c-ares references: vcpkg.exe install drogon:x64-windows-static

To Reproduce Steps to reproduce the behavior:

  1. Start Windows 10 x64
  2. Install Visual Studio 2019
  3. Install vcpkg (https://github.com/Microsoft/vcpkg)
  4. Run "vcpkg.exe install drogon:x64-windows-static"

Expected behavior Should compile ;)

Error Messages trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_library_init referenced in function "public: cdecl trantor::AresResolver::LibraryInitializer::LibraryInitializer(void)" (??0LibraryInitializer@AresResolver@trantor@@QEAA@XZ) trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_library_cleanup referenced in function "public: cdecl trantor::AresResolver::LibraryInitializer::~LibraryInitializer(void)" (??1LibraryInitializer@AresResolver@trantor@@QEAA@XZ) trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_init_options referenced in function "private: void cdecl trantor::AresResolver::init(void)" (?init@AresResolver@trantor@@AEAAXXZ) trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_destroy referenced in function "public: virtual cdecl trantor::AresResolver::~AresResolver(void)" (??1AresResolver@trantor@@UEAA@XZ) trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_set_socket_callback referenced in function "private: void cdecl trantor::AresResolver::init(void)" (?init@AresResolver@trantor@@AEAAXXZ) trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_gethostbyname referenced in function "private: void cdecl trantor::AresResolver::resolveInLoop(class std::basic_string<char,struct std::char_traits,class std::allocator > const &,class std::function<void cdecl(class trantor::InetAddress const &)> const &)" (?resolveInLoop@AresResolver@trantor@@AEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$function@$$A6AXAEBVInetAddress@trantor@@@Z@4@@Z) trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_timeout referenced in function "private: void cdecl trantor::AresResolver::resolveInLoop(class std::basic_string<char,struct std::char_traits,class std::allocator > const &,class std::function<void cdecl(class trantor::InetAddress const &)> const &)" (?resolveInLoop@AresResolver@trantor@@AEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$function@$$A6AXAEBVInetAddress@trantor@@@Z@4@@Z) trantor.lib(AresResolver.cc.obj) : error LNK2019: unresolved external symbol imp_ares_process_fd referenced in function "private: void cdecl trantor::AresResolver::onRead(int)" (?onRead@AresResolver@trantor@@AEAAXH@Z)

Additional context Add any other context about the problem here.

an-tao commented 4 years ago

@rbugajewski @cstratopoulos @LilyWangL Do you know why this happens? I have no idea. Thanks very much.

rbugajewski commented 4 years ago

@an-tao I’ve also no idea, as I’m primary on macOS or other Unices / Linuxes these days. Maybe it has something to do with the project setup (see https://stackoverflow.com/questions/14890847/how-to-solve-error-lnk2019)?

an-tao commented 4 years ago

But when runing vcpkg install drogon:x64-windows, very thing is ok. It's a strange error with the static compilation. Thanks so much.

interfector18 commented 4 years ago

My best guess is CARES_STATICLIB should be defined, because I'm guessing it was compiled statically, but when trantor includes ares.h it's not defined and it goes down the path of __declspec(dllimport), which makes the linker look for __imp_[function] that is called just [function] inside the static lib. Afaik this is MSVC specific behavior.

For reference, part of ares.h

#ifdef CARES_STATICLIB
#  define CARES_EXTERN
#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
#  if defined(CARES_BUILDING_LIBRARY)
#    define CARES_EXTERN  __declspec(dllexport)
#  else
#    define CARES_EXTERN  __declspec(dllimport)
#  endif
#elif defined(CARES_BUILDING_LIBRARY) && defined(CARES_SYMBOL_HIDING)
#  define CARES_EXTERN CARES_SYMBOL_SCOPE_EXTERN
#else
#  define CARES_EXTERN
#endif
an-tao commented 4 years ago

@interfector18 Thanks so much. I'll try to add CARES_STATICLIB macro when statically building.

haraldegger commented 4 years ago

@interfector18 Thanks so much. I'll try to add CARES_STATICLIB macro when statically building.

Thank you for taking care of this, I know this is not the most critical thing in the world. If it comes in handy for you I can do a test at any time, I have everything set up to do it.

an-tao commented 4 years ago

@interfector18 , You are right, the CARES_STATICLIB macro fixes errors of c-ares library. but there are some other compilation erros of libpq and openssl, they maybe caused by the same reason, I am trying to fix them.

interfector18 commented 4 years ago

@interfector18 , You are right, the CARES_STATICLIB macro fixes errors of c-ares library. but there are some other compilation erros of libpq and openssl, they maybe caused by the same reason, I am trying to fix them.

Glad to help, you should paste them here.

an-tao commented 4 years ago

@interfector18 , You are right, the CARES_STATICLIB macro fixes errors of c-ares library. but there are some other compilation erros of libpq and openssl, they maybe caused by the same reason, I am trying to fix them.

Glad to help, you should paste them here.

Thanks so much. here are the errors:

LINK Pass 1: command "C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1426~1.288\bin\Hostx64\x64\link.exe drogon_ctl\CMakeFiles\drogon_ctl.dir\cmd.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\create.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\create_controller.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\create_filter.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\create_model.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\create_plugin.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\create_project.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\create_view.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\help.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\main.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\press.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\version.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\cmake.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\config.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\demoMain.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\filter_cc.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\filter_h.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\gitignore.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\model_cc.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\model_h.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\model_json.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\plugin_cc.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\plugin_h.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\restful_controller_base_cc.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\restful_controller_base_h.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\restful_controller_cc.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\restful_controller_custom_cc.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\restful_controller_custom_h.cc.obj drogon_ctl\CMakeFiles\drogon_ctl.dir\restful_controller_h.cc.obj /out:drogon_ctl\drogon_ctl.exe /implib:drogon_ctl\drogon_ctl.lib /pdb:drogon_ctl\drogon_ctl.pdb /version:0.0 /machine:x64 /nologo /debug /INCREMENTAL /subsystem:console drogon.lib ws2_32.lib Rpcrt4.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\trantor.lib ws2_32.lib Rpcrt4.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\cares.lib shlwapi.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\jsoncpp.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\libpq.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\mariadbclient.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\sqlite3.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\libssl.lib C:\Users\antao\vcpkg\installed\x64-windows-static\debug\lib\libcrypto.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:drogon_ctl\CMakeFiles\drogon_ctl.dir/intermediate.manifest drogon_ctl\CMakeFiles\drogon_ctl.dir/manifest.res" failed (exit code 1120) with the following output:
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_set_noblock referenced in function PQconnectPoll
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_snprintf referenced in function PQconnectPoll
libpq.lib(fe-secure-openssl.obj) : error LNK2001: unresolved external symbol pg_snprintf
libpq.lib(win32.obj) : error LNK2001: unresolved external symbol pg_sprintf
libpq.lib(fe-connect.obj) : error LNK2001: unresolved external symbol pg_sprintf
libpq.lib(fe-exec.obj) : error LNK2001: unresolved external symbol pg_sprintf
libpq.lib(fe-protocol2.obj) : error LNK2001: unresolved external symbol pg_sprintf
libpq.lib(fe-auth.obj) : error LNK2001: unresolved external symbol pg_sprintf
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_fprintf referenced in function defaultNoticeProcessor
libpq.lib(fe-exec.obj) : error LNK2001: unresolved external symbol pg_fprintf
libpq.lib(encnames.obj) : error LNK2001: unresolved external symbol pg_fprintf
libpq.lib(fe-misc.obj) : error LNK2001: unresolved external symbol pg_fprintf
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pgwin32_fopen referenced in function parseServiceFile
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol strlcpy referenced in function PQcancel
libpq.lib(fe-protocol2.obj) : error LNK2001: unresolved external symbol strlcpy
libpq.lib(fe-protocol3.obj) : error LNK2001: unresolved external symbol strlcpy
libpq.lib(fe-secure-openssl.obj) : error LNK2001: unresolved external symbol strlcpy
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_get_encoding_from_locale referenced in function PQsetClientEncoding
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol inet_net_ntop referenced in function getHostaddr
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_gai_strerror referenced in function PQconnectPoll
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol __imp_FreeCredentialsHandle referenced in function pqDropConnection
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol __imp_DeleteSecurityContext referenced in function pqDropConnection
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_getaddrinfo_all referenced in function PQconnectPoll
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_freeaddrinfo_all referenced in function release_conn_addrinfo
libpq.lib(fe-connect.obj) : error LNK2019: unresolved external symbol pg_link_canary_is_frontend referenced in function connectDBStart
libpq.lib(fe-exec.obj) : error LNK2019: unresolved external symbol pg_tolower referenced in function PQfnumber
libpq.lib(fe-exec.obj) : error LNK2019: unresolved external symbol pg_vsnprintf referenced in function pqInternalNotice
libpq.lib(pqexpbuffer.obj) : error LNK2001: unresolved external symbol pg_vsnprintf
libpq.lib(fe-protocol2.obj) : error LNK2019: unresolved external symbol pg_strcasecmp referenced in function pqSetenvPoll
libpq.lib(fe-protocol3.obj) : error LNK2001: unresolved external symbol pg_strcasecmp
libpq.lib(fe-secure-common.obj) : error LNK2001: unresolved external symbol pg_strcasecmp
libpq.lib(fe-auth.obj) : error LNK2019: unresolved external symbol pg_md5_encrypt referenced in function PQencryptPassword
libpq.lib(fe-auth.obj) : error LNK2019: unresolved external symbol AcquireCredentialsHandleA referenced in function pg_SSPI_startup
libpq.lib(fe-auth.obj) : error LNK2019: unresolved external symbol InitializeSecurityContextA referenced in function pg_SSPI_continue
libpq.lib(fe-auth.obj) : error LNK2019: unresolved external symbol FreeContextBuffer referenced in function pg_SSPI_continue
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol pg_strong_random referenced in function pg_fe_scram_build_verifier
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol pg_b64_encode referenced in function build_client_first_message
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol pg_b64_decode referenced in function read_server_first_message
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol pg_b64_enc_len referenced in function build_client_first_message
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol pg_b64_dec_len referenced in function read_server_first_message
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol pg_saslprep referenced in function pg_fe_scram_init
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_HMAC_init referenced in function verify_server_signature
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_HMAC_update referenced in function verify_server_signature
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_HMAC_final referenced in function verify_server_signature
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_SaltedPassword referenced in function calculate_client_proof
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_H referenced in function calculate_client_proof
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_ClientKey referenced in function calculate_client_proof
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_ServerKey referenced in function verify_server_signature
libpq.lib(fe-auth-scram.obj) : error LNK2019: unresolved external symbol scram_build_verifier referenced in function pg_fe_scram_build_verifier
libpq.lib(fe-secure-openssl.obj) : error LNK2019: unresolved external symbol pg_strerror_r referenced in function initialize_SSL
libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp_CertOpenStore referenced in function capi_open_store
libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp_CertCloseStore referenced in function capi_find_key
libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp_CertEnumCertificatesInStore referenced in function capi_find_cert
libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp_CertFindCertificateInStore referenced in function capi_find_cert
libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp_CertDuplicateCertificateContext referenced in function capi_load_ssl_client_cert
libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp_CertFreeCertificateContext referenced in function capi_find_key
libcrypto.lib(e_capi.obj) : error LNK2019: unresolved external symbol __imp_CertGetCertificateContextProperty referenced in function capi_cert_get_fname
drogon_ctl\drogon_ctl.exe : fatal error LNK1120: 43 unresolved externals
interfector18 commented 4 years ago

It seems to me there is a missing include, as non __imp_ symbols are always defined, and __imp_ symbols just link to them, and also a vcpkg issue between pq and openssl, as pq is looking for __imp_ or imported symbols while statically linking, thus possibly a missing define when vcpkg builds pq.

From greping for dllimport inside openssl, it seems it's not a missing define, but an extra one, specifically OPENSSL_OPT_WINDLL

# if defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
#  define OPENSSL_EXPORT extern __declspec(dllexport)
#  define OPENSSL_EXTERN extern __declspec(dllimport)
# else
#  define OPENSSL_EXPORT extern
#  define OPENSSL_EXTERN extern
# endif