At the moment I'm trying to get the JUCE audio framework to work from Cython. As such, I first want to get a small and simple example running by showing an AlertWindow through the JUCE framework, but at the moment I seem to be having two small problems: 1. I have a problem with calling an enum from the JUCE framework 2. I don't know how to include the entire framework for compilation and linking.
My setup.py (called with "python3 setup.py build_ext --inplace"):
# Cython compile instructions
from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize
compile_args = ['-g', '-std=c++11', '-stdlib=libc++']
extensions = [Extension('testb', ['src/JUCE/testb.pyx'],
extra_compile_args=compile_args,
include_dirs = ["JUCE/modules"],)]
setup(
name='My app',
ext_modules=cythonize(extensions)
)
My testb.pyx (Problem 1 is here):
# distutils: language = c++
cdef extern from "JuceLibraryCode/JuceHeader.h" namespace "juce":
cdef cppclass AlertWindow:
AlertWindow(String, String, AlertIconType)
cdef class PyAlertWindow:
cdef AlertWindow *thisptr
def __cinit__(self):
self.thisptr = new AlertWindow("", "", NoIcon) # Don't know how to call the enum right here
def __dealloc__(self):
del self.thisptr
@staticmethod
def showAlertWindow(b):
print("at least this works")
Furthermore I continuously get these type of errors, which are as far as I know caused by the fact that the rest of the framework is not getting compiled and included/linked. How would I do this?
ImportError:
dlopen(<project root>/build/lib/testb.cpython-36m-darwin.so, 2): Symbol not found: __ZN4juce6StringC1Ev
Referenced from:
<project root>/build/lib/testb.cpython-36m-darwin.so
Expected in: flat namespace
in <project root>/build/lib/testb.cpython-36m-darwin.so
Also, with the --inplace flag, all compiled files get dumped in my main folder, which does not seem very scaleable, especially with larger frameworks. How do I make sure all .so-files end up in so they are easily referenced? Or are there better ways of dealing with this?
Ok, so with the help of @ead I was able to get a step further. The code now looks as follows:
# setup.py
from setuptools import setup
from setuptools.extension import Extension
from Cython.Build import cythonize
compile_args = ['-g', '-std=c++11', '-stdlib=libc++']
extensions = [Extension('testb', ['src/program/testb.pyx'],
extra_compile_args=compile_args,
include_dirs = ["JUCE/modules"],
libraries=["NewProject"], #the name of your library, WHICH MIGHT BE DIFFERENT FROM THE FILENAME!
library_dirs=["src/program/JuceLibraryCode"] #where your library is placed.
)]
setup(
name='My app',
ext_modules=cythonize(extensions)
)
And my Cython file:
# testb.pyx
# distutils: language = c++
from libcpp.string cimport string
cdef extern from "JuceLibraryCode/JuceHeader.h":
cdef cppclass AlertWindow:
AlertWindow(String, String, AlertIconType, Component*)
cdef cppclass Component:
Component()
cdef cppclass String:
String(string)
cdef extern from "JuceLibraryCode/JuceHeader.h" namespace "juce::AlertWindow":
ctypedef enum AlertIconType:
NoIcon
QuestionIcon
WarningIcon
InfoIcon
cdef class PyAlertWindow:
cdef AlertWindow *thisptr
def __cinit__(self):
self.thisptr = new AlertWindow(String(""), String(""), AlertIconType(NoIcon), NULL)
def __dealloc__(self):
del self.thisptr
And the example is now compiling fine. However, when I import the resulting package I get the following error:
ImportError: dlopen(<project root>/testb.cpython-36m-darwin.so, 2): Symbol not found: _CGAffineTransformIdentity
Referenced from: <project root>/testb.cpython-36m-darwin.so
Expected in: flat namespace
in <project root>/testb.cpython-36m-darwin.so
Which seems to be related to Cocoa (here) or CoreGraphics (here) (which I also believe is the successor to Cocoa). So how would I solve this? Do I need to include the framework CoreGraphics and if so, how? (simply adding the flag -framework CoreGraphics results in clang: error: unknown argument: '-framework CoreGraphics' unfortunately)
Thanks in advance for your answers!