Linker flag positions in CMake 3.5 - python

I have a pretty strange question: how do I make CMake 3.5 put the linker flags AFTER the files?
I am trying to compile a C++ which calls up a Python script. I have these two lines in my CMakeList.cpp :
add_executable (Python_trivium PyCall.cpp)
set_target_properties (Python_trivium PROPERTIES COMPILE_FLAGS "${PYTHON_CFLAGS}" Python_trivium PRIVATE "${PYTHON_LDFLAGS}")
This generates a Linking error. With "make VERBOSE=1" I can see that the linker command is as follows:
/usr/bin/c++ -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpython2.7 -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions CMakeFiles/Python_trivium.dir/PyCall.cpp.o -o Python_trivium
Where the flags are BEFORE the files. I get a "undefined reference" error for each command from Python.h, such as
/home/portolan/emanuele/MAST_project/pyhelper.hpp:12: undefined reference to `Py_Initialize'
If I invert and put the flags AFTER the files everything works:
/usr/bin/c++ CMakeFiles/Python_trivium.dir/PyCall.cpp.o -o Python_trivium -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpython2.7 -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
Is there a way to ask CMake to format the linker command line this way?
Thanks,
Michele

I discovered that my error was in trying to do it manually. CMake can do it better for me:
find_package(PythonLibs REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS})
message("PYTHONLIBS_VERSION_STRING: ${PYTHONLIBS_VERSION_STRING}")
Unfortunately it finds 3.5, while I would need 2.7....

Related

Compling Python3 to a binary excutable on mac

I'm tying to compile a python 3 command line program to a binary executable on Mac OS X. I'm following these directions
Compile main Python program using Cython
My install of python3 was done with homebrew but when I try to run
gcc -Os -I /usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/Headers -o at_analyzer at_analyzer.c -lpython3.5m -lpthread -lm -lutil -ldl -v
I get the following error :
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -disable-free -disable-llvm-verifier -discard-value-names -main-file-name at_analyzer.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 274.1 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -I /usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/Headers -Os -fdebug-compilation-dir /Users/alex/Source/AT_analyzer -ferror-limit 19 -fmessage-length 150 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -vectorize-loops -vectorize-slp -o /var/folders/8l/3c5cnrvj1hg_qbr73dz1pnq40000gn/T/at_analyzer-e9d098.o -x c at_analyzer.c
clang -cc1 version 8.0.0 (clang-800.0.42.1) default target x86_64-apple-darwin16.1.0
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/Headers
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -o at_analyzer /var/folders/8l/3c5cnrvj1hg_qbr73dz1pnq40000gn/T/at_analyzer-e9d098.o -lpython3.5m -lpthread -lm -lutil -ldl -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a
ld: library not found for -lpython3.5m
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Any help would be greatly appreciated.
Figured it out. I needed to specify the -L flag with the path that points to the library.
gcc -Os -I /usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/Headers -L /usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib -o at_analyzer at_analyzer.c -lpython3.5m -lpthread -lm -lutil -ldl -v

Python distutils gcc path

I'm trying to cross-compile the pycrypto package, and I'm getting closer and closer however, I've hit an issue I just can't figure out.
I want distutils to use the cross-compile specific gcc- so I set the CC env var and it seems to respect the setting for the first invocation of the compiler, but thats it.
export CC="/opt/teeos/buildroot/output/host/usr/bin/i586-linux-gcc"
/opt/teeos/buildroot/output/host/usr/bin/i586-linux-gcc -fno-strict-aliasing -fwrapv -Wall -Wstrict-prototypes -fPIC -std=c99 --sysroot=/opt/teeos/buildroot/output/staging -I/opt/teeos/buildroot/output/staging/usr/include/python2.7 -O3 -fomit-frame-pointer -Isrc/ -I/usr/include/python2.7 -c src/_fastmath.c -o build/temp.linux-i686-2.7/src/_fastmath.o
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions build/temp.linux-i686-2.7/src/_fastmath.o -lgmp -o build/lib.linux-i686-2.7/Crypto/PublicKey/_fastmath.so
unable to execute gcc: No such file or directory
I temporarily moved my systems gcc so it can't be found.
How do I make distutils respect the CC=/opt/buildroot... option for every invocation of the compiler / set the path to the GCC / LD I want distutils to use?
This sounds similar to another answer I recently gave for customizing the distutils compiler. You'll also need to define LDSHARED which is the command used to produce the final shared object. See if this works:
>>> from distutils import sysconfig
>>> sysconfig.get_config_var('LDSHARED')
'gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions'
>>> sysconfig.get_config_var('CC')
'gcc -pthread'
Then replace gcc with your desired compiler and options in the CC and LDSHARED environment variables:
% LDSHARED="i586-linux-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions" \
CC="i586-linux-gcc -pthread" python setup.py build

PyCUDA / Copperhead doesn't appear to recognise 64-bit machines

Two problems I'm having with copperhead at the minute, which I suspect are related.
Running a sample file (samples/axpy.py) generated lots of little warnings, but this one stood out.
g++ -pthread -fno-strict-aliasing -g -O2 -g -fwrapv -O2 -Wall -fPIC -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -DNDEBUG -I/usr/include/python2.6 -I/usr/local/lib/python2.6/dist-packages/copperhead-0.1a1-py2.6.egg/copperhead/include -I/usr/local/cuda/include /tmp/codepy-compiler-cache-v5-uid1000/202478034fea29b82d046b259bd6f43e/module.o /tmp/codepy-compiler-cache-v5-uid1000/fdcb04ede426b146cfce8894e99eeb57/gpu.o -L/usr/lib -L/usr/local/cuda/lib -L/usr/local/cuda/lib64 -lcuda -lcudart -lboost_python-gcc43-mt -lpthread -ldl -lutil -o /tmp/codepy-compiler-cache-v5-uid1000/202478034fea29b82d046b259bd6f43e/codepy.temp.202478034fea29b82d046b259bd6f43e.module.so
/usr/bin/ld: skipping incompatible /usr/local/cuda/lib/libcudart.so when searching for -lcudart
/usr/bin/ld: cannot find -lboost_python-gcc43-mt
collect2: ld returned 1 exit status
Few things to notice;
g++ is has correctly picked up the correct CUDA lib dir to use (lib64), but doesn't see libcudart.so in there, which it is.
/usr/local/cuda/lib64/libcudart.so.4.0.12: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped
Next, boost_python isn't found; I've heard from a few places that this is due to ubuntu breaking a package convention somewhere, and people has said they've fixed it by changing the pycuda configure options, but haven't said what to change it to... (Example)
Anyone got any ideas for either the cudart or boot issues?
It is finding libcudart. What you
are seeing is only an informational
warning: -L options are
searched in order and the linker is
finding the 32 bit version first,
because you gave
-L/usr/local/cuda/lib before -L/usr/loca/cuda/lib64.
For the libboost_python problem,
just link with -lboost_python. The
Ubuntu systems I use (64 bit
10.04LTS with boost-python 1.40) have a series of cascading symbolic
links to that canonical
library name that make the linker
find the correct library without any
further intervention.

g++ linking and swig

I have a cpp file with functions that I'm using in python with SWIG. I use the following commands to compile the source and create the file to use with python.
swig -c++ -python mini.i
g++ -O2 -c mini.cpp -I/usr/include/python2.4 -I/usr/lib/python2.4
g++ -O2 -c mini_wrap.cxx -I/usr/include/python2.4 -I/usr/lib/python2.4
g++ -shared mini.o mini_wrap.o -o _mini.so
I'm trying now to use GSL in my source cpp source file. If I was just compiling the GSL file I would do
g++ -lgsl -lgslcblas -lm -o mini.o mini.cpp
I've tried adding the -lgsl -lgslcblas -lm to the lines for the swig compile but I get
g++: -lgsl: linker input file unused because linking not done
g++: -lgslcblas: linker input file unused because linking not done
g++: -lm: linker input file unused because linking not done
How can I link the gsl libraries? Thanks
Swig does no linking, as the warning message states. Put the -lgsl etc. on the link command, which is your last g++ command.

Linking GSL (or other library) statically into a shared library

Note: Despite the mentioning of Python in the following there is a good chance for my problem not to be Python related at all. If I am not mistaken the “module” I mention is equivalent to a C library—at least for the concerns of my problem.
On Debian I am trying to create a Python module with C, which in turn uses the GSL. The following Makefile successfully compiles it:
CC = gcc -Wall -fPIC -O3
NAME = meinzeug
matrizenwuerfler: $(SRC)
$(CC) -o $(NAME).o -I/usr/lib/python2.5/site-packages/numpy/core/include -I/usr/include/python2.5 -c $(NAME).c
$(CC) -shared -o $(NAME).so -lgsl -lgslcblas -lm $(NAME).o
Because this module is supposed to be used by (Linux) machines other than mine, I want the GSL to be included into the module (or be shipped with it).
However, if I add -static as option to the last line of the Makefile, I get the following error:
gcc -Wall -fPIC -O3 -shared -static -o meinzeug.so -lgsl -lgslcblas -lm meinzeug.o
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.3.2/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/4.3.2/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
Adding -Wl,-Bstatic before the library linking results in a different error:
gcc -Wall -fPIC -O3 -shared -o meinzeug.so -Wl,-Bstatic -lgsl -lgslcblas -lm meinzeug.o
/usr/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status
Other Stuff, that did not work: Recompiling GSL with fPIC, -static-libgcc, permutating the options.
What I did not try yet, is compiling gcc with fPIC or similar.
Try
gcc -Wall -fPIC -O3 -shared -o meinzeug.so /usr/lib/libgsl.a -lm meinzeug.
as you cannot do
gcc -Wall -fPIC -O3 -shared -static ... # shared and static at the same time ?
so you would provide the static library of GSL alongside with your code.
At the end of the day, I would punt and keep the dependency on the GSL. Just about everybody has it, and the API is pretty stable.
The ordering of the library calls is important. For me, it meant sending the /usr/lib/libgsl.a to the end of the command. That solved it.

Categories

Resources