I'm trying to embed python in my C++ project. I need to do it in order to use some functions that implement the Kolmogorov-Smirnov Test that are not available in C++.
For now I'm just trying to see if Xcode is able to link and compile a simple program that embeds Python. The code I'm trying to compile is the following:
#include<Python/Python.h>
int main(int argc, const char * argv[]) {
Py_Initialize();
PyObject* variable;
Py_Finalize();
return 0;
}
As far as I can understand from the instructions I've read here: 1. Embedding Python in Another Application - 1.6 Compiling and Linking under Unix-like systems and here: Python/C API Reference Manual - Introduction in order for this to compile I have to add some additional flags to the compiler and the linker.
In order to find out which flags should I add, I've run the following two commands in my terminal (of which I include the corresponding output):
$ python3.6-config --cflags
-I/Users/user/anaconda3/include/python3.6m -I/Users/user/anaconda3/include/python3.6m -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/user/anaconda3/include -arch x86_64 -I/Users/user/anaconda3/include -arch x86_64
$ python3.6-config --ldflags
-lpython3.6m -ldl -framework CoreFoundation -Wl,-stack_size,1000000 -framework CoreFoundation
Where I replaced the actual name of my user folder with user
.
Now, in order to add these flags to the Xcode compiler and linker I went to my project settings window and under Build Settings -> Other C Flags
and Build Settings -> Other Linker Flags
I added the flags that I've reported above.
But when I compile I get this error:
Apple Mach-O Linker (ld) Error Group
clang: error: linker command failed with exit code 1 (use -v to see invocation)
And it doesn't go away even if I comment all the lines in the main
function except for return 0
.
I don't understand what I'm doing wrong.
I'm using Xcode 8.3.2
and my Python distribution is: Python 3.6.1 |Anaconda 4.4.0
Ok, I think I've found a solution. Not sure if it's actually the right one (since I'm not an expert and I don't really understand the reason why now it works), but I'm going to post it anyway.
The thing is that if you look at the instructions in this page: 1. Embedding Python in Another Application - 1.6. Compiling and Linking under Unix-like systems you can see that when executing the command python3.6-config --ldflags
the output contains a flag -L/opt/lib/python3.4/config-3.4m
while in my case it doesn't.
So after figuring out that the flag that gave me the linking error was -lpython3.6m
, I thought that maybe it was due to the fact that the linker couldn't find the directory in which my python distribution was or something like that.
So I looked in my hard drive for a path to a folder with a name similar to the one shown on the webpage and I found that /Users/user/anaconda3/lib/python3.6/config-3.6m-darwin
was a path to a folder with a name very similar to the one I was looking for, except for the "-darwin" at the end of the folder's name that's probably there because I'm on a macOS distribution (maybe that's why the command python3.6-config --ldflags
didn't find it? I don't know).
After this I just added -L/Users/user/anaconda3/lib/python3.6/config-3.6m-darwin
at the beginning of Xcode's "Other Liker Flags" and everything (almost) compiled just fine.
I say "almost" because I also had to rename the include
at the beginning of my code from #include<Python/Python.h>
to #include<Python.h>
(maybe because by using the first one I'm including the system default Python distribution while with the second I'm including the Anaconda one? Again, I don't know).
Anyway now everything compiles just fine and so I thought to share how I did it in case somebody else is in the same situation.