Skip to content

mingw builds #923

@real-or-random

Description

@real-or-random

#922 got me interested in mingw, so I started playing around and reading. Here are some notes that may save others time and should be converted into a PR at some point. I'd appreciate any comments from people more familiar with the topic (@gmaxwell, @theuni).

secp256k1 has been written to support mingw builds. As demonstrated in #922, these builds (still) work in general. But a few caveats apply.

Here are some simple issues to start with:

The real fun starts with DLLs (shared libaries) which are a pain in the ass. When creating a DLL, one needs to declare exported symbols explictly using __declspec (dllexport). We currently do this via in secp256k1.h via SECP256K1_API when SECP256K1_BUILD is defined.

When using the library (i.e., SECP256K1_BUILD is not defined), one can declare the symbols explicitly using __declspec (dllimport). We currently don't do this because the only problem is a small overhead when calling a DLL function but the code still works. The reason to avoid __declspec (dllimport) is that static linking will fail. (I verified this by adding the declspec and configuring with --disable-shared.) Unfortunately there's no way of telling whether we'll link statically or not, so the best possible thing is to have a macro that the user can set. (See also https://www.sourceware.org/autobook/autobook/autobook_137.html, https://autotools.io/libtool/windows.html, #314).

  • We currently don't have this macro. We could add it, maybe it's useful for someone and it won't create problems because it's not set by default.
  • In order to be able to create DLLs at all, we need to add -no-undefined to the appropriate libtool LDFLAGS like libsecp256k1_la_LDFLAGS = -no-undefined. Otherwise libtool will tell us libtool: warning: undefined symbols not allowed in x86_64-w64-mingw32 shared libraries; building static only as seen on CI in Add mingw32-w64/wine CI build #922. A workaround for now and for testing is to call make with make LDFLAGS=-no-undefined. Apparently this flag does not hurt on Linux, and none of the guides I found mentions that this should be only set on Windows, so we can just set this unconditionally.
  • When building the benchmarks, we'll still get warnings like ./.libs/lt-bench_internal.c:41:5: warning: '_putenv' redeclared without dllimport attribute: previous dllimport ignored [-Wattributes] but these are in the C code of the libtool wrapper binary, not in our code. (On Windows, this is an entire wrapper binary and not just a sh script as on Linux). I have no idea if this is a libtool bug or the issue is on our side but apparently the wrapper binary works, so we can simply ignore these for now. Having warnings is not elegant though, so it may still be interesting to ask on the libtool list to see what's going on.
  • According to the libtool and gnulib docs, we should add win32-dll to LT_INIT. For me and CI, it seems to work without this, but I guess we should simply add it.

Uff.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions