Skip to content

Commit e7e86fe

Browse files
real-or-randomsipa
authored andcommitted
build: Add SECP256K1_API_VAR to fix importing variables from DLLs
This fixes a build issue with MSVC. While MSVC imports *functions* from DLLs automatically when building a consumer of the DLL, it does not import *variables* automatically. In these cases, we need an explicit __declspec(dllimport). This commit simply changes our logic to what the libtool manual suggests, which has a very comprehensive writeup on the topic. Note that in particular, this solution is carefully designed not to break static linking. However, as described in the libtool manual, statically linking the library with MSVC will output warning LNK4217. This is still the best solution overall, because the warning is merely a cosmetic issue.
1 parent 1423c3d commit e7e86fe

File tree

3 files changed

+27
-20
lines changed

3 files changed

+27
-20
lines changed

include/secp256k1.h

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -145,21 +145,28 @@ typedef int (*secp256k1_nonce_function)(
145145
# define SECP256K1_NO_BUILD
146146
#endif
147147

148-
/** At secp256k1 build-time DLL_EXPORT is defined when building objects destined
149-
* for a shared library, but not for those intended for static libraries.
150-
*/
151-
152-
#ifndef SECP256K1_API
153-
# if defined(_WIN32)
154-
# if defined(SECP256K1_BUILD) && defined(DLL_EXPORT)
155-
# define SECP256K1_API __declspec(dllexport)
156-
# else
157-
# define SECP256K1_API
148+
/* Symbol visibility. See libtool manual, section "Windows DLLs". */
149+
#if defined(_WIN32) && !defined(__GNUC__)
150+
# ifdef SECP256K1_BUILD
151+
# ifdef DLL_EXPORT
152+
# define SECP256K1_API __declspec (dllexport)
153+
# define SECP256K1_API_VAR extern __declspec (dllexport)
158154
# endif
159-
# elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
160-
# define SECP256K1_API __attribute__ ((visibility ("default")))
155+
# elif defined _MSC_VER
156+
# define SECP256K1_API
157+
# define SECP256K1_API_VAR extern __declspec (dllimport)
158+
# elif defined DLL_EXPORT
159+
# define SECP256K1_API __declspec (dllimport)
160+
# define SECP256K1_API_VAR extern __declspec (dllimport)
161+
# endif
162+
#endif
163+
#ifndef SECP256K1_API
164+
# if defined(__GNUC__) && (__GNUC__ >= 4) && defined(SECP256K1_BUILD)
165+
# define SECP256K1_API __attribute__ ((visibility ("default")))
166+
# define SECP256K1_API_VAR extern __attribute__ ((visibility ("default")))
161167
# else
162168
# define SECP256K1_API
169+
# define SECP256K1_API_VAR extern
163170
# endif
164171
#endif
165172

@@ -231,10 +238,10 @@ typedef int (*secp256k1_nonce_function)(
231238
*
232239
* It is highly recommended to call secp256k1_selftest before using this context.
233240
*/
234-
SECP256K1_API extern const secp256k1_context *secp256k1_context_static;
241+
SECP256K1_API_VAR const secp256k1_context *secp256k1_context_static;
235242

236243
/** Deprecated alias for secp256k1_context_static. */
237-
SECP256K1_API extern const secp256k1_context *secp256k1_context_no_precomp
244+
SECP256K1_API_VAR const secp256k1_context *secp256k1_context_no_precomp
238245
SECP256K1_DEPRECATED("Use secp256k1_context_static instead");
239246

240247
/** Perform basic self tests (to be used in conjunction with secp256k1_context_static)
@@ -631,10 +638,10 @@ SECP256K1_API int secp256k1_ecdsa_signature_normalize(
631638
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
632639
* extra entropy.
633640
*/
634-
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
641+
SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
635642

636643
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
637-
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default;
644+
SECP256K1_API_VAR const secp256k1_nonce_function secp256k1_nonce_function_default;
638645

639646
/** Create an ECDSA signature.
640647
*

include/secp256k1_ecdh.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,15 @@ typedef int (*secp256k1_ecdh_xonly_hash_function)(
4343

4444
/** An implementation of SHA256 hash function that applies to compressed public key.
4545
* Populates the output parameter with 32 bytes. */
46-
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
46+
SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_sha256;
4747

4848
/** A default ECDH hash function (currently equal to secp256k1_ecdh_hash_function_sha256).
4949
* Populates the output parameter with 32 bytes. */
50-
SECP256K1_API extern const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
50+
SECP256K1_API_VAR const secp256k1_ecdh_hash_function secp256k1_ecdh_hash_function_default;
5151

5252
/** An implementation of SHA256 hash function that applies to the X coordinate.
5353
* Populates the output parameter with 32 bytes. */
54-
SECP256K1_API extern const secp256k1_ecdh_xonly_hash_function secp256k1_ecdh_xonly_hash_function_sha256;
54+
SECP256K1_API_VAR const secp256k1_ecdh_xonly_hash_function secp256k1_ecdh_xonly_hash_function_sha256;
5555

5656
/** Compute an EC Diffie-Hellman secret in constant time
5757
*

include/secp256k1_schnorrsig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ typedef int (*secp256k1_nonce_function_hardened)(
6161
* Therefore, to create BIP-340 compliant signatures, algo must be set to
6262
* "BIP0340/nonce" and algolen to 13.
6363
*/
64-
SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
64+
SECP256K1_API_VAR const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340;
6565

6666
/** Data structure that contains additional arguments for schnorrsig_sign_custom.
6767
*

0 commit comments

Comments
 (0)