Using libspotify .dll/.lib files in MinGW32 compiling pySpotify - python

Using MinGW32 on a Windows PC I am trying to compile pySpotify. The first error was that libspotify/api.h was missing. I fixed this by copying the appropriate folder from libspotify into C:\MinGW\include. However now dllwrap is now failing with ld linking. The binaries Spotify distribute are libspotify.dll and libspotify.lib. No matter where I put them (pySpotify folder/subfolders, temp build folder/subfolders and MinGW folder/subfolders) or what I name them (.a, .o & .so) it still shows the same error messages.
The pertinent error is:
C:\MinGW\bin\dllwrap.exe -mdll -static --output-lib build\temp.win32-2.7\Release\src\lib_spotify.a --def build\temp.win32-2.7\Release\src\_spotify.def -s build\temp.win32-2.7\Release\src\module.o build\temp.win32-2.7\Release\src\session.o build\temp.win32-2.7\Release\src\link.o build\temp.win32-2.7\Release\src\track.obuild\temp.win32-2.7\Release\src\album.o build\temp.win32-2.7\Release\src\albumbrowser.o build\temp.win32-2.7\Release\src\artist.o build\temp.win32-2.7\Release\src\artistbrowser.o build\temp.win32-2.7\Release\src\search.o build\temp.win32-2.7\Release\src\playlist.o build\temp.win32-2.7\Release\src\playlistcontainer.o build\temp.win32-2.7\Release\src\playlistfolder.o build\temp.win32-2.7\Release\src\image.o build\temp.win32-2.7\Release\src\user.o build\temp.win32-2.7\Release\src\pyspotify.o build\temp.win32-2.7\Release\src\toplistbrowser.o -LC:\Python26\libs -LC:\Python26\PCbuild -lspotify -lpython26 -lmsvcr90 -o build\lib.win32-2.7\spotify\_spotify.pyd
c:/mingw/bin/../lib/gcc/mingw32/4.7.2/../../../../mingw32/bin/ld.exe: cannot find -lspotify
collect2.exe: error: ld returned 1 exit status
dllwrap: gcc exited with status 1
error: command 'dllwrap' failed with exit status 1
bok says on github that:
You need to add the API headers in the include path (add something like -I~\libspotify\include to your compiler options) and the shared library in the library path (add -L~\libspotify\lib to your linker options). This will allow the compiler to find the necessary include files, and your linker to find the necessary binary objects.
However the distutils Extension class seems to be deprecated and hard to find documentation for (I believe this is where custom compiler options need to go). Appreciate that ~ may need changed to %USERPROFILE% or similar. Similarly %PYTHONPATH%\Lib\distutils\distutils.cfg has little documentation beyond the [build] compiler=mingw32 stanza. This makes editing the compile/link commands and their options impossible to change.
How do you compile pySpotify on Windows?
EDIT:
By using Python 2.6 and copying libspotify.dll/libspotify.lib to C:\Python26\PCbuild and renaming them to spotify.dll/libspotify.lib I now receive another error message from ld:
C:\MinGW\bin\dllwrap.exe -mdll -static --output-lib build\temp.win32-2.6\Release\src\lib_spotify.a --def build\temp.win32-2.6\Release\src\_spotify.def -s build\temp.win32-2.6\Release\src\module.o build\temp.win32-2.6\Release\src\session.o build\temp.win32-2.6\Release\src\link.o build\temp.win32-2.6\Release\src\track.obuild\temp.win32-2.6\Release\src\album.o build\temp.win32-2.6\Release\src\albumbrowser.o build\temp.win32-2.6\Release\src\artist.o build\temp.win32-2.6\Release\src\artistbrowser.o build\temp.win32-2.6\Release\src\search.o build\temp.win32-2.6\Release\src\playlist.o build\temp.win32-2.6\Release\src\playlistcontainer.o build\temp.win32-2.6\Release\src\playlistfolder.o build\temp.win32-2.6\Release\src\image.o build\temp.win32-2.6\Release\src\user.o build\temp.win32-2.6\Release\src\pyspotify.o build\temp.win32-2.6\Release\src\toplistbrowser.o -LC:\Python26\libs -LC:\Python26\PCbuild -lspotify -lpython26 -lmsvcr90 -o build\lib.win32-2.6\spotify\_spotify.pyd
_spotify.exp: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status
dllwrap: gcc exited with status 1
error: command 'dllwrap' failed with exit status 1

Not having access to a mingw installation at the moment, I can suggest a few things.
First, ld is known to be picky about order of arguments. Strangely, when I googled for "ld argument order", I got a bunch of pages suggesting that the order doesn't matter, but I have been burned several times by this. I've had the most success with the following argument order:
Switches to ld (ie, -Wall)
Library search paths (ie, -LPATH)
Object files
Libraries (ie, -lspotify)
I noticed in your linker output some references to amd64. I'm not sure how you compiled the other object files that you have, but since libspotify is 32-bit on Windows, I'm guessing that mixing 32/64 bit here is not going to work out too well.
The last thing I can think of is that perhaps the dll extension is confusing to ld, have you tried changing the filename to libspotify.so? I know this is kind of a shot in the dark, but otherwise I'm not sure how to help you further.

I guess you are trying to link a 64bit version of pyspotify against a 32bit version of libspotify. Try to rebuild pyspotify adding the -m32 to CFLAGS and CXXFLAGS

I've added some instructions on how I got it to compile on the actual ticket for the issue. Let me Know if it helped you!
https://github.com/mopidy/pyspotify/issues/63

Related

Python.h compiling error: collect2.exe Id returned 1 exit status

So, I've searched all around the web and I couldn't find anything.
I'm started with python, and I made a TKinter application. At first, I tried to compile it to an .exe file, but that didn't work. So now I'm embedding python in C++. Every single time I try to compile it (using Dev-C++), I get the error:
C:\Users\*****\AppData\Local\Temp\ccsqSJ5V.o [program-name].cpp:(.text+0x10): undefined reference to `__imp_Py_Initialize'
C:\Users\*****\AppData\Local\Temp\ccsqSJ5V.o [program-name].cpp:(.text+0x25): undefined reference to `__imp_PyRun_SimpleStringFlags'
C:\Users\*****\AppData\Local\Temp\ccsqSJ5V.o [program-name].cpp:(.text+0x2e): undefined reference to `__imp_Py_Finalize'
F:\Documents\Videos\[program-name]\program\collect2.exe [Error] ld returned 1 exit status
F: stands for the flash drive.
In the Dev-c++ options, I added:
-Wall -I\C:\Users\*****\AppData\Local\Programs\Python\Python35\include
So this is the full command:
g++.exe "F:\Documents\Videos\[program-name]\program\[program-name].cpp" -o "F:\Documents\Videos\[program-name]\program\[program-name].exe" -Wall -I\C:\Users\*****\AppData\Local\Programs\Python\Python35\include -I"C:\Programma's\Dev-C++\MinGW64\include" -I"C:\Programma's\Dev-C++\MinGW64\x86_64-w64-mingw32\include" -I"C:\Programma's\Dev-C++\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include" -I"C:\Programma's\Dev-C++\MinGW64\lib\gcc\x86_64-w64-mingw32\4.9.2\include\c++" -I"C:\Users\*****\AppData\Local\Programs\Python\Python35\include" -L"C:\Programma's\Dev-C++\MinGW64\lib" -L"C:\Programma's\Dev-C++\MinGW64\x86_64-w64-mingw32\lib" -static-libgcc
My question is: how do I deal with this?
And please note: I haven't got administrator privileges, I'm just a standard user.
Python version: 3.5.1
Dev-C++ version: 5.11
GCC version: I don't know, but I'll find it out if needed :)
EDIT: Because of the duplicate mark by NathanOliver, I'll ask it like this: which command line variables do I have to add to compile it?
The linker is complaining bacause it can't find a group of references about some python stuff, as a matter of fact I don't see any python library in the g++ invocation.
You need to had something like this -lpython3.5.1 to tell g++ to link against the python library (assuming python is installed in your system, else you will have to add the path to the library using the -L option).
More resources on g++ makefiles and linking:
https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

How can I build my C extensions with MinGW-w64 in Python?

So I have a few Python C extensions I have previously built for and used in 32 bit Python running in Win7. I have now however switched to 64 bit Python, and I am having issues building the C extension with MinGW-w64.
I made the changes to distutils as per this post, but I am getting some weird errors suggesting something is wrong:
$ python setup.py build
running build
running build_ext
building 'MyLib' extension
c:\MinGW64\bin\x86_64-w64-mingw32-gcc.exe -mdll -O -Wall -Ic:\Python27\lib\site-packages\numpy\core\include -Ic:\Python27\include -Ic:\Python27\PC -c MyLib.c -o build\temp.win-amd64-2.7\Release\mylib.o
MyLib.c: In function 'initMyLib':
MyLib.c:631:5: warning: implicit declaration of function 'Py_InitModule4_64' [-Wimplicit-function-declaration]
writing build\temp.win-amd64-2.7\Release\MyLib.def
c:\MinGW64\bin\x86_64-w64-mingw32-gcc.exe -shared -s build\temp.win-amd64-2.7\Release\mylib.o build\temp.win-amd64-2.7\Release\MyLib.def -Lc:\Python27\libs -Lc:\Python27\PCbuild\amd64 -lpython27 -o build\lib.win-amd64-2.7\MyLib.pyd
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x13d): undefined reference to `__imp_PyExc_ValueError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1275): undefined reference to `__imp_PyExc_ValueError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1eef): undefined reference to `__imp_PyExc_ImportError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1f38): undefined reference to `__imp_PyExc_AttributeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1f4d): undefined reference to `__imp_PyCObject_Type'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1f61): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1fc7): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x1ffe): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x2042): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x206c): undefined reference to `__imp_PyExc_RuntimeError'
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x208a): more undefined references to `__imp_PyExc_RuntimeError' follow
build\temp.win-amd64-2.7\Release\mylib.o:MyLib.c:(.text+0x20a7): undefined reference to `__imp_PyExc_ImportError'
collect2.exe: error: ld returned 1 exit status
error: command 'x86_64-w64-mingw32-gcc' failed with exit status 1
I have googled around quite a bit to find information, but it's not easy to find a definite answer. Could someone shed some light on this? What further changes should I do to be able to successfully build C extensions for 64 bit Python in Win7?
EDIT:
After some helpful pointers in cgohlke's comments below I managed to generate libpython27.a. However after following the advice on this post (2nd to last) I still had a the __imp_Py_InitModule4_64 error. After some serious Google-fu I managed to trip over this post telling me to rename the Py_InitModule4 line to Py_InitModule4_64. After that everything worked swimmingly.
This worked for me with Python 3.3 :
create static python lib from dll
python dll is usually in C:/Windows/System32; in msys shell:
gendef.exe python33.dll
dlltool.exe --dllname python33.dll --def python33.def --output-lib libpython33.a
mv libpython33.a C:/Python33/libs
use swig to generate wrappers
e.g., swig -c++ -python myExtension.i
wrapper MUST be compiled with MS_WIN64, or your computer will crash when you import the class in Python
g++ -c myExtension.cpp -I/other/includes
g++ -DMS_WIN64 -c myExtension_wrap.cxx -IC:/Python33/include
shared library
g++ -shared -o _myExtension.pyd myExtension.o myExtension_wrap.o -lPython33 -lOtherSharedLibs -LC:/Python33/libs -LC:/path/to/other/shared/libs
make sure all shared libs (gdal, OtherSharedLibs) are in your PATH
(windows does not use LD_LIBRARY_PATH or PYTHONPATH)
in Python, just: import myExtension
voila!
I realize this is an old question, but it is still the top search result. Today, in 2019, I was able to do this:
https://github.com/PetterS/quickjs/commit/67bc2428b8c0716538b4583f4f2b0a2a5a49106c
In short:
Make sure a 64-bit version of mingw-w64 is in the PATH.
Monkey-patch distutils:
import distutils.cygwinccompiler
distutils.cygwinccompiler.get_msvcr = lambda: []
Some differences in the shell w.r.t. escaping.
extra_link_args = ["-Wl,-Bstatic", "-lpthread"] in order to link statically and not have extra runtime deps.
pipenv run python setup.py build -c mingw32 now works.
Here is a example code for VC++ Build Tools
https://github.com/starnight/python-c-extension/tree/master/00-HelloWorld
You could try:
python setup.py -c mingw32
However this is not work for me.
My Solution is:
install Anaconda 64bit python 3.6
install mingw64
add mingw64/bin to PATH
compile dll from c file by
gcc -c libmypy.c -IC:\Users\{user_name}\Anaconda3\pkgs\python-3.6.4-h6538335_1\include
gcc -shared -o libmypy.dll libmypy.o -LC:\Users\{user_name}\Anaconda3\pkgs\python-3.6.4-h6538335_1\libs -lPython36
load dll file in .py script
from ctypes import *
m = cdll.LoadLibrary(r"C:\{path_to_dll}\libmypy.dll")
print(m.hello())
I created a monkey-patch for setuptools to let you to build_ext with mingw64 on Windows easily. See https://github.com/imba-tjd/mingw64ccompiler
I used this thread to wade through learning how to make a C extension, and since most of what I learned is in it, I thought I'd put the final discovery here too, so that someone else can find it if they are looking.
I wasn't trying to compile something big, just the example in Hetland's Beginning Python. Here is what I did (the example C pgm is called palindrome.c). I'm using Anaconda with python 3.7 in it, and the TDM-GCC version of MinGW64. I put all of the tools used into my Path, and all of the paths needed in PYTHONPATH, and the ..\Anaconda3 directory into PYTHON_HOME. I still ended up using explicit paths on some things.
I created the libpython37.a library with gendef.exe and dlltool.exe as Mark said above, and put it in ..\Anaconda3\libs.
I followed the prescription in Hetland:
gcc -c palindrome.c
gcc -I$PYTHON_HOME -I$PYTHON_HOME/Include -c palindrome_wrap.c
The second failed, the compiler couldn't find Python.h, the following worked:
gcc -I[somedirectories]\Anaconda3\Include -c palindrome_wrap.c
I then did, as many have said, including Hetland 3rd ed.,
gcc -shared palindrome.o palindrome_wrap.o [somedirectories]/Anaconda3/libs/libpython37.a -o _palindrome.dll
This did not work. Even with the Load Library cswu used (which I found elsewhere, too).
So I gendef'd _palindrome.dll and couldn't find the function in it, "is_palindrome" in the exports. I went through some of the SWIG documentation, and declared the function both in the %{ %} section and below it, both extern, that finally got the function extern'd in palindrome_wrap.c as it should have been. But no export, so I went back into palindrome.c and redeclared the function as:
declspec(dllexport) extern int __stdcall is_palindrome(char* text)
and redeclared it in palindrome.i in both places as above with this signature.
Partial success! It got listed in the Export section when I gendef'd _palindrome.dll and I could do cswu's call using Load Library. But still not do what Hetland says and do
import _palindrome
in Python.
Going back to all the sources again, I could not figure this out. I finally started reading the SWIG documentation from the beginning leaving no stone unturned -- Searching through the manual doesn't produce the place found.
At the end of Introduction Sec. 2.7 Incorporating Into a Build System, under the sample Make process, it says:
"The above example will generate native build files such as makefiles, nmake files and Visual Studio projects which will invoke SWIG and compile the generated C++ files into _example.so (UNIX) or _example.pyd (Windows). For other target languages on Windows a dll, instead of a .pyd file, is usually generated."
And that's the answer to the last problem:
The compile step for the dll should read:
gcc -shared palindrome.o palindrome_wrap.o [somedirectories]/Anaconda3/libs/libpython37.a -o _palindrome.pyd
(I didn't go back and change out my declspec declarations so I don't know whether they were necessary, so they were still there too).
I got a file, _palindrome.pyd
Which if in the PYTHONPATH (mine was local) works, and one can then do
import _palindrome
from _palindrome import is_palindrome
and use the exported, properly wrapped and packaged C function, compiled with TDM-GCC, in python as promised. gcc, which is MinGW64 in a different installation, knows how to do the .pyd file. I diffed the dll and pyd since they were the same byte length. They are not the same at hundreds of points.
Hope this helps someone else.

A multitude of problems trying to install Python bcrypt on Windows (x64)

This problem has been mentioned elsewhere, but it does not provide a working solution, so I would still like to keep a ticket open.
c:\Users\me\Desktop\temp\py-bcrypt-0.2>setup.py install build --compiler=min
gw32
running install
running build
running build_py
running build_ext
building 'bcrypt._bcrypt' extension
C:\MinGW\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\Python27\include -IC:\Python27\PC -c bcrypt/bcrypt_python.c -o build\temp.win32-2.7\Release\bcrypt\bcrypt_python.o
bcrypt/bcrypt_python.c:29:26: error: expected declaration specifiers or '...' before 'u_int8_t'
bcrypt/bcrypt_python.c:29:38: error: expected declaration specifiers or '...' before 'u_int16_t'
bcrypt/bcrypt_python.c:29:49: error: expected declaration specifiers or '...' before 'u_int8_t'
bcrypt/bcrypt_python.c: In function 'bcrypt_encode_salt':
bcrypt/bcrypt_python.c:56:2: error: too many arguments to function 'encode_salt'
bcrypt/bcrypt_python.c:29:6: note: declared here
error: command 'gcc' failed with exit status 1
This is after getting rid of the initial “error: Setup script exited with error: Unable to find vcvarsall.bat”, I am left with what seems like a Gordic knot. pip and easy-install do not work. I have also read a number of other articles.
I don’t need to implement bcrypt at the moment, so it is not an urgent matter, but obviously, implementing a secure password protection is vital.
The simplest way I found was to download and install windows binaries, rather than trying to compile myself. This guy has some on bitbucket
supposing you are using mingw64, you should change _MSC_VER in _WIN32 on ifdefs into bcrypt.c, bcrypt_python.c and pybc_blf.h
(I've also replied the other question)

SWIG build debugging tools/tips

I am trying to build M2Crypto 0.21.1 with OpenSSL 1.0.0c (or 0.9.7m) for Python 2.5.4 on windows, but SWIG is conspiring against me. I've tried both SWIG 2.0.1 and SWIG 1.3.40 and I get the same error:
swigging SWIG/_m2crypto.i to SWIG/_m2crypto_wrap.c
C:\Development\swigwin-1.3.40\swig.exe -python -IC:\Development\Python-2.5.4\include -IC:\Development\Python-2.5.4\PC -Ic:\Development\openssl-0.9.7m\include -includeall -o SWIG/_m2crypto_wrap.c SWIG/_m2crypto.i
c:\Development\openssl-0.9.7m\include\openssl\opensslv.h(1): Error: Syntax error in input(1).
All permutations of OpenSSL/SWIG show this error. I've tried invoking swig by hand and passing all the "extra verbose" options I could, but none of them are even close to informative. What else can I do to try to find the true source of this problem?
(There are suggestions on this site to edit the .i file for M2Crypto, but 0.21.1 already has the suggested changes integrated)
Actually the problem here isn't SWIG, but I'll leave this question/answer for the next M2Crypto user that comes along - maybe it will help them.
The problem is that the M2Crypto setup.py by default points to <your openssl dir>/include, but if that openssl directory is the source tree, include/ isn't the right place to look (on windows at least) - you need to be looking in inc32/, otherwise opensslv.h is just a line pointing to a different file, which is why SWIG bombs out on line 1.

How to link C lib against python for embedding under Windows?

I am working on an application written in C. One part of the application should embed python and there is my current problem. I try to link my source to the Python library but it does not work.
As I use MinGW I have created the python26.a file from python26.lib with dlltool and put the *.a file in C:/Program Files (x86)/python/2.6/libs.
Therefore, I compile the file with this command:
gcc -shared -o mod_python.dll mod_python.o "-LC:\Program Files (x86)\python\2.6\libs" -lpython26 -Wl,--out-implib,libmod_python.a -Wl,--output-def,mod_python.def
and I get those errors:
Creating library file: libmod_python.a
mod_python.o: In function `module_init':
mod_python.c:34: undefined reference to `__imp__Py_Initialize'
mod_python.c:35: undefined reference to `__imp__PyEval_InitThreads'
... and so on ...
My Python "root" folder is C:\Program Files (x86)\python\2.6
The Devsystem is a Windows Server 2008
GCC Information: Reading specs from C:/Program Files (x86)/MinGW/bin/../lib/gcc/mingw32/3.4.5/specs
Configured with: ../gcc-3.4.5-20060117-3/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared --enable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchronization --enable-libstdcxx-debug
Thread model: win32
gcc version 3.4.5 (mingw-vista special r3)
What I do wrong? How I get it compiled and linked :-)?
Cheers, gregor
Edit:
I forgot to write information about my Python installation: It's the official python.org installation 2.6.1
... and how I created the python.a file:
dlltool -z python.def --export-all-symbols -v c:\windows\system32\python26.dll
dlltool --dllname c:\Windows\system32\python26.dll --def python.def -v --output-lib python26.a
Well on Windows the python distribution comes already with a libpython26.a in the libs subdir so there is no need to generate .a files using dll tools.
I did try a little example with a single C file toto.c:
gcc -shared -o ./toto.dll ./toto.c -I/Python26/include/ -L/Python26/libs -lpython26
And it works like a charm. Hope it will help :-)
Python (at least my distribution) comes with a "python-config" program that automatically creates the correct compiler and linker options for various situations. However, I have never used it on Windows. Perhaps this tool can help you though?
IIRC, dlltool does not always work. Having python 2.6 + Wow makes things even more less likely to work. For numpy, here is how I did it. Basically, I use obdump.exe to build the table from the dll, which I parse to generate the .def. You should check whether your missing symbols are in the .def, or otherwise it won't work.

Categories

Resources