I'm trying to build a Python extension which links to APR. And this time it's on MS Windows... (It works on Linux).
Here's where the build fails, the command, and the output formatted for readability:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe
/nologo
/INCREMENTAL:NO
/LTCG
/DLL
/MANIFEST:EMBED,ID=2
/MANIFESTUAC:NO
/LIBPATH:c:\dev\protopy\lib/apr
/LIBPATH:c:\bin\python\Libs
/LIBPATH:c:\dev\protopy\.venv\libs
/LIBPATH:c:\dev\protopy\.venv\PCbuild\amd64
"/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64"
"/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.10240.0\ucrt\x64"
"/LIBPATH:C:\Program Files (x86)\Windows Kits\8.1\lib\winv6.3\um\x64"
apr-1.lib
/EXPORT:PyInit_wrapped build\temp.win-amd64-3.6\Release\protopy/lib/descriptors.obj
build\temp.win-amd64-3.6\Release\protopy/lib/binparser.obj
build\temp.win-amd64-3.6\Release\protopy/lib/defparser.obj
build\temp.win-amd64-3.6\Release\protopy/lib/protopy.lex.obj
build\temp.win-amd64-3.6\Release\protopy/lib/protopy.tab.obj
build\temp.win-amd64-3.6\Release\protopy/lib/pyhelpers.obj
build\temp.win-amd64-3.6\Release\protopy/lib/list.obj
build\temp.win-amd64-3.6\Release\protopy/wrapper.obj
/OUT:build\lib.win-amd64-3.6\protopy\wrapped.cp36-win_amd64.pyd
/IMPLIB:build\temp.win-amd64-3.6\Release\protopy/lib\wrapped.cp36-win_amd64.lib
wrapper.obj : warning LNK4197: export 'PyInit_wrapped' specified multiple times; using first specification
Creating library build\temp.win-amd64-3.6\Release\protopy/lib\wrapped.cp36-win_amd64.lib \
and object build\temp.win-amd64-3.6\Release\protopy/lib\wrapped.cp36-win_amd64.exp
descriptors.obj : error LNK2001: unresolved external symbol \
__imp_apr_hash_set
(it actually misses all symbols I've used, not just this one).
I've built the apr-1.lib
by running nmake -f Makefile.win
in APR's top-level directory before, and this is how I produced libapr-1.lib
. Then I renamed to apr-1.lib
it and put it in c:\dev\protopy\lib/apr
, so the linker is actually able to find it, but it cannot find the required symbols...
How can I see what symbols are in the library? (Maybe I compiled something wrong?)
OK, I found dumpbin.exe
, but now I see that the symbol in the apr-1.lib
is called __imp__apr_hash_set
(notice the second double underscore), but the linker looks for __imp_apr_hash_set
(single underscore). What gives? They were compiled with the same compiler / linker...
Is there anything specific to building Python extensions on MS Windows that makes it work in this way? (I only tried this once in my life, and couldn't get it to work, but for different reasons).
According to APR project document
choose either aprutil or libaprutil (for static or dynamic libraries)
means apr-1.lib-->static
and libapr-1.lib -->dynamic
and
To target the static .lib versions of the library, the consuming compiliation must define the macros APR_DECLARE_STATIC and APU_DECLARE_STATIC. This prevents the apr and apr-util symbols from being tagged as __declspec(dllimport), eliminating compiliation warnings and speeding up execution.