-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
build: Improvements to symbol visibility logic on Windows #1362
Changes from all commits
85aecf4
297c85a
d2117f0
69918b8
5267c8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,27 +133,56 @@ typedef int (*secp256k1_nonce_function)( | |
# define SECP256K1_NO_BUILD | ||
#endif | ||
|
||
/* Symbol visibility. See https://gcc.gnu.org/wiki/Visibility */ | ||
/* DLL_EXPORT is defined internally for shared builds */ | ||
#if defined(_WIN32) | ||
# ifdef SECP256K1_BUILD | ||
# ifdef DLL_EXPORT | ||
/* Symbol visibility. */ | ||
#if defined(_WIN32) || defined(__CYGWIN__) | ||
# if defined(SECP256K1_STATICLIB) && defined(SECP256K1_DLL) | ||
# error "At most one of SECP256K1_STATICLIB and SECP256K1_DLL must be defined." | ||
# endif | ||
/* GCC for Windows (e.g., MinGW) and for Cygwin accept the __declspec syntax | ||
* for MSVC compatibility. A __declspec declaration implies (but is not | ||
* exactly equivalent to) __attribute__ ((visibility("default"))), and so we | ||
* actually want __declspec even on GCC, see "Microsoft Windows Function | ||
* Attributes" in the GCC manual and the recommendations in | ||
* https://gcc.gnu.org/wiki/Visibility. */ | ||
# if defined(SECP256K1_BUILD) | ||
# if defined(SECP256K1_DLL) || defined(DLL_EXPORT) | ||
/* Building libsecp256k1 as a DLL. (DLL_EXPORT is a libtool convention.) */ | ||
# define SECP256K1_API __declspec (dllexport) | ||
# define SECP256K1_API_VAR extern __declspec (dllexport) | ||
# endif | ||
# elif defined _MSC_VER | ||
# elif defined(SECP256K1_STATICLIB) | ||
/* Linking against static libsecp256k1 requested explicitly. */ | ||
# define SECP256K1_API | ||
# define SECP256K1_API_VAR extern | ||
# elif defined(SECP256K1_DLL) | ||
/* Linking against a libsecp256k1 DLL requested explicitly. */ | ||
# define SECP256K1_API __declspec (dllimport) | ||
# define SECP256K1_API_VAR extern __declspec (dllimport) | ||
# elif defined(_MSC_VER) | ||
/* No method requested explicitly. The following works on MSVC for both | ||
* static and dynamic linking, as long as if at least one function is | ||
* imported (i.e., not only variables are imported), which should be the case | ||
* for any meaningful program that uses the libsecp256k1 API. The drawback of | ||
* the following is that it may provoke linker warnings LNK4217 and LNK4286. | ||
* See "Windows DLLs" in the libtool manual. */ | ||
# define SECP256K1_API | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While touching this code, we can exploit one more optimization. From Microsoft docs:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, but we shouldn't touch it here in the The specific combination
is precisely what always works for MSVC (if one is willing to accept the warning):
https://www.gnu.org/software/libtool/manual/html_node/Windows-DLLs.html#Windows-DLLs But in general, yes, the introduction of |
||
# define SECP256K1_API_VAR extern __declspec (dllimport) | ||
# elif defined DLL_EXPORT | ||
# elif defined(DLL_EXPORT) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shoudn't it be OR'ed with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, if An alternative option is to drop this "guess" based on
(https://www.gnu.org/software/libtool/manual/html_node/Windows-DLLs.html#Windows-DLLs) But with this PR, we get better methods for telling the tools what is intended. And I believe that "Explicit is better than implicit" and "In the face of ambiguity, refuse the temptation to guess.". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think? Should we remove this branch entirely? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove it. As a Libtool-only convention, using the
Indeed. |
||
/* No method requested explicitly and we're not on MSVC. We make an educated | ||
* guess based on libtool's DLL_EXPORT convention: If the importing program | ||
* is itself a DLL, then it is likely that it also wants to consume | ||
* libsecp256k1 as a DLL. See "Windows DLLs" in the libtool manual. */ | ||
# define SECP256K1_API __declspec (dllimport) | ||
# define SECP256K1_API_VAR extern __declspec (dllimport) | ||
# endif | ||
#endif | ||
#ifndef SECP256K1_API | ||
# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD) | ||
/* Building libsecp256k1 on non-Windows using GCC or compatible. */ | ||
# define SECP256K1_API __attribute__ ((visibility ("default"))) | ||
# define SECP256K1_API_VAR extern __attribute__ ((visibility ("default"))) | ||
# else | ||
/* All cases not captured above. */ | ||
# define SECP256K1_API | ||
# define SECP256K1_API_VAR extern | ||
# endif | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a recommendation to use the
SECP256K1_STATICLIB
macro?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a sentence in an earlier version, but I removed it because it's probably clear by "No method requested explicitly." Let me bring it back.