Which version of `gcc` supports the `--no-undefined` switch? - python

I am trying to compile pynifti package from source (long story involving Anaconda Python distribution).
After running make, I receive the following error:
gcc: error: unrecognized command line option ‘--Wl,--no-undefined’
Indeed, the manual (man gcc) contains no information about --no-undefined switch. My version of gcc is 4.8.5. Also, I can not find the no-undefined option in https://gcc.gnu.org/onlinedocs/gcc/Option-Index.html#Option-Index
However, from Force GCC to notify about undefined references in shared libraries I infer that it is a valid switch at least for some version of gcc.

This switch is a linker option for ld. It is not directly part of GCC but it is only encapsulated in a -Wl option to be passed to the linker (you seem to have --Wl which is wrong).
Edit:
Yugr deserves part of the credit as he pointed out the incorrect --Wl option!

Related

How to install C++ dependencies "from source" for a Python package on Mac OS?

There is a Github repo containing Python "bindings" for a C++ library that I am interested in playing with. The README has abundant information about how to install the C++ library on Linux like machines, but no information about how to do so with a mac OS.
I have also opened up an issue requesting the README installation instructions include mac OS-specific installs in addition to linux. There hasn't been any activity on that issue.
Here are the two repos:
(Python) https://github.com/asiffer/python3-libspot
(C++) https://github.com/asiffer/libspot
Since the C++ package isn't available for installing via Brew/pip/anaconda, I'm not sure how to get going.
What I've Tried:
I have tried ./configure, and make. There is no ./configure file.
To address the lack of ./configure, read about a tool called autoconf which supposedly generates ./configure for you. I installed it with brew, but am not sure what arguments to pass it. These docs were pretty hard to understand: https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Making-configure-Scripts.html
Just using make results in the error clang: error: unsupported option '-fopenmp'That sent me down a whole different rabbit hole which had me adding lines to the Makefile:
CPP = /usr/local/opt/llvm/bin/clang
CPPFLAGS = -I/usr/local/opt/llvm/include -fopenmp
LDFLAGS = -L/usr/local/opt/llvm/lib
omp_hello: omp_hello.c
$(CPP) $(CPPFLAGS) $^ -o $# $(LDFLAGS)
That felt dangerous because I have no idea what any of that stuff means. Plus it resulted in a new error: *** missing separator. Stop.
So then I read that's probably due to using "soft" tabs instead of "hard" tabs which can be identified using cat -e -t -v makefile_name. I found the one line where a "hard" tab was missing (the indented line above) and inserted it. This resulted in a new error:
make: *** No rule to make target `omp_hello.c', needed by `omp_hello'. Stop.
Next, following the advice of Yang Yushi and his follow on comments, I changed lines 39 and 40 according to his answer, plus added the locations of some additional files to the CXXFLAGS variable:
-I//opt/homebrew/Cellar/libomp/11.0.1/include
-L/opt/homebrew/Cellar/libomp/11.0.1/lib
And this got me a little further. Next, OSX didn't like where this script was trying to install, as explained by this answer. So I changed these two lines in the makefile which seemed to dictate install location:
INSTALL_HEAD_DIR = $(DESTDIR)/usr/include/libspot
INSTALL_LIB_DIR = $(DESTDIR)/usr/lib
to
INSTALL_HEAD_DIR = $(DESTDIR)/usr/local/include/libspot
INSTALL_LIB_DIR = $(DESTDIR)/usr/local/lib
And that indeed got me a little farther. Next I ran into an error complaining about the flat -t at these lines in the makefile:
#install -t $(INSTALL_LIB_DIR) $(LIB_DIR)/*.so
#install -t $(INSTALL_HEAD_DIR) $(INC_DIR)/*.h
So I deleted those flags, which then resulted in this error:
Checking the headers installation directory (/usr/local/include/libspot)
Checking the library installation directory (/usr/local/lib)
Installing the shared library (libspot.so)
install: /usr/local/lib: Inappropriate file type or format
For which I can find no reading material and have no clue how to fix. Any further assistance appreciated.
Here's a list of SO and other resources I've perused trying to answer this question:
Enable OpenMP support in clang in Mac OS X (sierra & Mojave)
makefile error: make: *** No rule to make target `omp.h' ; with OpenMP
makefile:4: *** missing separator. Stop
http://www.idryman.org/blog/2016/03/10/autoconf-tutorial-1/
https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Making-configure-Scripts.html
https://developer.gnome.org/anjuta-build-tutorial/stable/create-autotools.html.en
My Question
How do I proceed.
If you know how to do this, could you also include a brief explanation of the concepts behind each step? I'd be happy to learn a little instead of just copying and pasting commands in the right order.
Compile the C++ source code with Apple Clang
I downloaded the prjoect (libspot) and successfully compiled it on my Mac. I change two lines (39 and 40) in the Makefile to make it work. (Following this answer)
CC = clang++ # change from g++ to default Apple clang
CXXFLAGS = -std=c++11 -Wall -pedantic -Xpreprocessor -fopenmp -lomp # additional flags
You should get the binary file by just type make with a "correct" Makefile.
(If you see something like "cant find omp.h", add -I/usr/local/opt/libomp/include to the CXXFLAGS.)
For the Question
The error message in the updated question description
make: *** No rule to make target omp_hello.c', needed by omp_hello'. Stop.
is telling us that the file omp_hello.c is missing. The Makefile is written to compile the source code omp_hello.c to an executable binary file omp_hello. If I have the C source file (omp_hello.c), the Makefile will allow me to compile by just typing
make
instead of
/usr/local/opt/llvm/bin/clang \
-I/usr/local/opt/llvm/include -fopenmp \
-L/usr/local/opt/llvm/lib \
omp_hello.c -o omp_hello
This is just a normal compile process, it has nothing to do with Python. The error message is saying the source code to be compiled (omp_hello.c) is missing.
It looks like this is a small project with custom Makefile. Normally you compile the code with just make. The error you got seems to suggest the lack of llvm. You may want to try install llvm following this answer.
Usually it comes to running brew install <your C++ package> or downloading the source code to some directory and running a set of commands:
./configure
make
make install
While usually it works, some packages can not be installed on Mac since their maintainers did not prepare configuration for Mac.

How to pass linker flags to f2py?

I am trying to wrap a set of Fortran files to Python using f2py. I am using the gfortran compiler via mingw64. The sources I am trying to wrap contain Lapack functions, so I built Lapack and Blas following the "Easy windows build" instructions on this webpage: https://icl.cs.utk.edu/lapack-for-windows/lapack/#build. I am now able to compile my source file by running
gfortran foo.F90 -ffree-line-length-512 -llapack -lblas -fdec-math -Wl,-allow-multiple-definition
As you can see I need to pass a set of options, which are not really all that relevant here except for the last one -Wl,-allow-multiple-definition. I have found that if I do not include this option the file won't compile and I get a whole set of errors all ending with multiple definition of `_gfortran[...] where [...] contains some extra string, like for example _st_open'. Perhaps that last option is a bit of a hack, but at least the file compiles without issues.
However I do not know how to pass this linker option to f2py. Currently I run,
python -m numpy.f2py -llapack -lblas -c foo.F90
--fcompiler=gnu95 --compiler=mingw32 --f90flags="-ffree-line-length-512 -fdec-math -Wl,-allow-multiple-definition" -m foo_py
But this doesn't seem to do anything, I just get the same multiple definition error as if the linker flag wasn't included. So what syntax should I use?
Thanks!
EDIT: After some extensive googling it seems like f2py contains no option to pass linker flags to the compiler. So now I am wondering if there is some way to force the allow-multiple-definition option on the compiler globally.
I think the error itself must somehow originate in how I have built LAPACK and BLAS. Similar errors have been reported before, see https://icl.cs.utk.edu/lapack-forum/viewtopic.php?f=4&t=5315, but seemingly only in the built process and not during a fortran compile. Would there be alternative ways to build LAPACK such that I can easily incorporate it with gfortran?
Did you have a look at this: how to tell f2py module to look in current directory for shared object dependency
There the following is suggested:
set env variable export LDFLAGS=-Wl,-rpath=.
set env variable export NPY_DISTUTILS_APPEND_FLAGS=1
upgrade numpy to 1.16.0 or greater

Compile PyTorch with additional linker options

I have a modified version of the gloo library. I am able to compile and run programs that use this library (similar to what you can find in gloo/gloo/examples).
Now, I want to build pytorch with my library.
I replaced the third_party/gloo folder in PyTorch with my version of gloo and I am trying to compile it.
However, my version of gloo requires some additional libraries and special linker options. Where should these linker options be added in the pytorch build system?
Without these linker options, my compilation stops with the linker error:
/pytorch/build/lib/libcaffe2_gpu.so: undefined reference to <my code>
/pytorch/build/lib/libcaffe2.so: undefined reference to <my code>
The additional linker options should be added to:
the Caffe2_DEPENDENCY_LIBS variable in pytorch/caffe2/CMakeLists.txt with the command:
list(APPEND Caffe2_DEPENDENCY_LIBS <linker_options>)
the C10D_LIBS variable in pytorch/torch/lib/c10d/CMakeLists.txt with the command:
list(APPEND C10D_LIBS <linker_options>)
The additional libraries should have Position Independent Code (they must be compiled with the -fPIC flag).

Py_Initialize undefined reference

I want to add python functions in C++ code.
I made a GUI in gtk (on the Raspberry PI) and now I want to work with a camera module which is easy to handle in python. (I want to start a video directly when I push a button.)
So I included the file Python.h
#include <python3.4m/Python.h>
#include <python3.4m/pythonrun.h>
then I thought it should work, but when I try to compile Py_Initialize()
I get the error:
undefined reference to Py_Initialize.
I think this is strange because, when I type in, there came the selection for Py_Initialize.
In terms of headers you should be fine, since it compiled but failed at linking.
Now you need to link against the Python libraries. The way this is done largely depends on what toolchain you are using.
Maybe you can see my answer in another question:
if with python 3.x installed, maybe this command can work:
g++ hw.cpp `/usr/bin/python3-config --cflags` `/usr/python3-config --ldflags`
By the way, you should check you gcc and python version.
As I know, if gcc version is 5.4 and python version is 3.7, it doesn't work.(python 3.5 >is work)
When you run /usr/bin/python3-config --cflags, in fact, it is the compile option.
Set the python include folder and it static lib on gcc command line and put the python dynamic lib on LD_LIBRARY_PATH. Before Py_Initialize(), do not forget to set python home with Py_SetPythonHome(). These steps must be sufficient for your code compile and run.

How to install twisted 10.2.0 with pypy 1.4.1?

I can't install twisted 10.2.0 to my ubuntu box. After download twisted source I issue the command: pypy setup.py install. After that I receive the error:
building 'twisted.runner.portmap' extension
creating build/temp.linux-x86_64-2.5
creating build/temp.linux-x86_64-2.5/twisted
creating build/temp.linux-x86_64-2.5/twisted/runner
cc -I/builds/pypy-1.4.1-linux64/include -c twisted/runner/portmap.c -o build/temp.linux-x86_64-2.5/twisted/runner/portmap.o
cc -shared build/temp.linux-x86_64-2.5/twisted/runner/portmap.o -o build/lib.linux-x86_64-2.5/twisted/runner/portmap.pypy-14.so
/usr/bin/ld.bfd.real: build/temp.linux-x86_64-2.5/twisted/runner/portmap.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
build/temp.linux-x86_64-2.5/twisted/runner/portmap.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
error: command 'cc' failed with exit status 1
So, how can I fix it? Thanks.
That's a "bug" in twisted build. It might be or might not be a bug - twisted does not consider it's C extensions optional, although they're far from necessary for the most part. Twisted would still work if you just point PYTHONPATH to where it is situated, but without those C extensions.
You may be able to skip building extensions by commenting off the following line in setup.py (73):
conditionalExtensions = getExtensions(),
This should avoid collecting and trying to build extensions scattered in the directory tree.
As for now Twisted trunk could be compiled OK with PyPy (I used 1.6.1-dev0).
However in order to install Twisted you'd need to apply a patch to zipfile.py that I have submitted to stdlib.
zipfile.py 2.7.1+ leaks file descriptors because of CPython-oriented programming style used in zipfile.py
Therefore installation fails under PyPy that uses other GC model than CPython does.

Categories