Recompile with -fPIC option, but the option is already in the makefile - makefile

I get this error when I do the make:
relocation R_X86_64_32 against `vtable for Torch::MemoryDataSet' can not be used
when making a shared object; recompile with -fPIC
It says that I should recompile with the -fPIC option. I did that, adding
the -fPIC option to CFLAGS and CXXFLAGS, but I still get the same error. Is there any way to solve this? I have seen that this problem is related with the use of a 64-bit machine, and it is true that I am using one.

I had this problem quite a while back and if I remember correctly, the fix was moving the placement of -fPIC just after gcc in the command line. Made absolutely no sense, and less so now, but as I remember, that fixed it.

I encountered the same problem, but it had an extra twist. The answer by #clintm solved it, but I thought I would describe my variation of the problem here for future reference...
Makefile on 32-bit machine:
CXX=g++
CXXFLAGS= -O3 -Wall
...
...
%.o: %.c
$(CXX) $(CXXFLAGS) -fpic -c $<
libmylibrary.so: $(OBJECTS)
$(CXX) -shared -Wl,-soname,$# -o $# $(OBJECTS)
This compiled correctly. But the same Makefile failed when I tried it on a 64-bit machine. I changed "-fpic" to "-fPIC" and it still failed. I changed the object rule to:
%.o: %.c
$(CXX) -fPIC $(CXXFLAGS) -c $<
and it still failed.
Finally, I placed "-fPIC" in the actual compiler variable (so that now "-fPIC" appears in the rule for each object and the rule for the shared library):
CXX=g++ -fPIC
CXXFLAGS= -g -O3 -Wall
...
%.o: %.c
$(CXX) $(CXXFLAGS) -c -o $# $<
libalglib.so: $(OBJECTS)
$(CXX) -shared -Wl,-soname,$# -o $# $(OBJECTS)
And it worked!

Let's say you have some makefile like:
CFLAGS = -g -Wall
SOURCES = $(wildcard *.c)
OBJECTS = ...
TARGET = libmyawesomelib.a
all: $(TARGET) main
just add the -fPIC flag like so:
$(TARGET): CFLAGS += -fPIC
$(TARGET): $(OBJECTS)
.
.
.
so on so forth with the rest of the makefile.

I ran into this problem cross-compiling with the android-ndk toolchain. I ended up having to use
CC="$CROSS/bin/arm-linux-androideabi-gcc -pie --sysroot=$SYSROOT"
Neither -fPIC nor -fPIE worked for me in this situation.

I was cross compiling shadowsocks-libev on a CentOS 7 machine, the same problem happened to me, it works perfectly on my laptop with
CC=mipsel-unknown-linux-uclibc-gcc CXX=mipsel-unknown-linux-uclibc-g++ AR=mipsel-unknown-linux-uclibc-ar RANLIB=mipsel-unknown-linux-uclibc-ranlib make SHARED=1 CFLAGS=-fPIC
but on travis ci, it did not work, I have to add -fPIC to CC and CXX in order to get it to work
CC="mipsel-unknown-linux-uclibc-gcc -fPIC" CXX="mipsel-unknown-linux-uclibc-g++ -fPIC" AR=mipsel-unknown-linux-uclibc-ar RANLIB=mipsel-unknown-linux-uclibc-ranlib make SHARED=1

I had this issue after I upgraded gcc. I had one .o file (sqlite) that hadn't been cleaned by the Makefile and as a result I had this issue (assuming because it was compiled with an older version of gcc). After removing that file and rebuilding this error went away.

if the project you'd like to compile has a correct configure script use like this:
$ ./configure 'CFLAGS=-g -O2 -fPIC ....' --enable-some-thing
so the flag will be all the Makefile's rule ...
few days before i've need an elder ver. of VLC to compile on an x64 machine, it has a nice configure script ;-)

Related

How I change my Makefile so it has a specific DEBUG option?

Currently I have a very simple Makefile. When I run it, it compiles my code with some specific options so I can debug it later on. I would like to be able to execute it with a normal "make" without option that creates my code withouth debug option, and one more complex, that add such as debuging. Currently my makefile only compiles with the debug options avaiable, see here the makefile:
main: main.o comandos.o utils.o
main.o:
gcc -Wall -gstabs -DDEBUG -c src/main.c
comandos.o:
gcc -Wall -gstabs -DDEBUG -c src/comandos.c
utils.o:
gcc -Wall -gstabs -DDEBUG -c src/utils.c
clean:
rm main \
*.o
Any advise on how to customize it for both debugging and not debugging options? I was thinking to add a CFLAGS variable at the start, and supressing the variables at gcc lines, but not sure on how I can run on easy way differents values for CFLAGS, one for debuging, with -gstabs -DDEBUG, and only for normal, with only -Wall.
EDIT I: I am aware I can do different targets, and do a specific TARGET called Debug, but the issue I see there is that when I am generating a commands.o, for example, that will be used later on in target main, I already have commands.o precompiled with some specific flags. I am looking for away to have 2 differents targets generatings the same "commands.o", one with debbuging flags other with normal,
and have the main target being able to use the correct one.
I think I found the solution, my main problem was to define two different $FLAGS depending on the target, so I can have a default FLAGS when doing a "normal" release and different flags when I had a debug. I did it this way:
CFLAGS = -Wall
CC = gcc
main: main.o comandos.o utils.o
debug: CFLAGS = -Wall -gstabs -DDEBUG
debug: main
main.o:
$(CC) $(CFLAGS) -c src/main.c
comandos.o:
$(CC) $(CFLAGS) -c src/comandos.c
utils.o:
$(CC) $(CFLAGS) -c src/utils.c
clean:
rm main \
*.o
Not sure if this is the correct way to do it, but seems is working. Thks to #tripple to redirect me to How can I configure my makefile for debug and release builds?.

compiler error gcc-8: error: unrecognized command line option '-no-pie'

I am trying to compile using this makefile but got this error. I can compile using school's linux computer with gcc 6.3. I tried using my MacOS mojave using a few different version of gcc from homebrew (gcc-8, gcc-4.9, gcc-6) but I get this error consistently.
CC = gcc-8
OPT = -O3 -g
LIBS = -lz -lcvp -lz
FLAGS = -std=c++11 -L. $(LIBS) $(OPT) -no-pie
OBJ = myprogram.o
DEPS = cvp.h myprogram.h
all: cvp
cvp: $(OBJ)
$(CC) $(FLAGS) -o $# $^
%.o: %.cc $(DEPS)
$(CC) $(FLAGS) -c -o $# $<
.PHONY: clean
clean:
rm -f *.o cvp
Going off information found here: https://github.com/xd009642/tarpaulin/issues/7#issuecomment-317180523
The problem may very well be related to how gcc is built: "Builds of gcc that don't have the --enable-default-pie flag set at compile time because they are too old or have the --disable-default-pie flag just don't have the -no-pie linker flag"
You might need to update or recompile gcc for that environment to be able to use that flag if important to you.

Makefile: "No such file or directory" for target file

First, I should admit makefiles are something that I'm very inexperienced at, so I apologize if this is an error that I should have been able to solve myself, but I have spent several hours on this, including reading the various answers on this site, and have been unable to discover a solution.
With that said, I have created the following makefile to compile my code on a Linux machine; it completes the sub compilations just fine, but when it comes to making the output itself, xPlatST, it throws an error.
g++ -std=c+=11 -g -Wall -pthread -c -o xPlatST.o xPlatST.cpp
g++ -std=c+=11 -g -Wall -pthread -c -o stdafx.o stdafx.cpp
g++ -std=c+=11 -g -Wall -pthread -c xPlatST xPlatST.o stdafx.o -L../hwloc
g++ error: xPlatST: No such file or directory
make: *** [xPlatST] Error 1
I believe it seems to think that the xPlatST is one of it's compilation files and thus can't find it, but for the life of me I can't work out why.
hwloc is a third party library, and should be unrelated to this issue. The code compiles just fine when compiled from the command line directly.
My files are xPlatST.cpp, xPlatST.h, stdafx.cpp, stdafh.h
Code is as follows:
CXX = g++ -std=c++11
INCLUDES =
LIBS = -L../hwloc
CXXFLAGS = -Wall -g -pthread
OBJS = xPlatST.o stdafx.o
xPlatST: ${OBJS}
${CXX} ${CXXFLAGS} ${INCLUDES} -c $# ${OBJS} ${LIBS}
clean:
-rm xPlatST *.o
Any help would be greatly appreciated; thank you in advance.
Your assumption is correct. Your recipe is trying to use xPlatST as a source. Change the -c into a -o in your rule:
${CXX} ${CXXFLAGS} ${INCLUDES} -o $# ${OBJS} ${LIBS}
The -c flag tells the compiler to take all files, compile, and assemble them into an object file (.o). The -o flag specifies the destination file.

Creating a makefile for CUDA programs

I want to automate the compilation of a toy library using CUDA and C++. Then I write a Makefile as follows
CC=g++
NVCC=nvcc
CXXFLAGS= -fopenmp -O3 -Wextra -std=c++11
CUDAFLAGS= -std=c++11 -c -arch=sm_20
LIBS= -lopenblas -lpthread -lcudart -lcublas
LIBDIRS=-L/usr/local/cuda-7.5/lib64
INCDIRS=-I/usr/local/cuda-7.5/include
matrix_cuda.o: marix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
all: matrix_cuda.o
$(CC) -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o $(LIBDIRS) $(INCDIRS) $(LIBS) $(CXXFLAGS)
clean:
rm -rf test *.o
Typing make I get
make: *** No rule to make target `marix_cuda.cu', needed by `matrix_cuda.o'. Stop.
I never wrote a Makefile before. Where did I go wrong?
I think you have a typo in the CUDA file name
matrix_cuda.o: marix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
IMHO it should be
matrix_cuda.o: matrix_cuda.cu
$(NVCC) $(CUDAFLAGS) matrix_cuda.cu
This may take a couple of iterations.
1) First try this:
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works (and produces matrix_cuda.o, I presume), remove matrix_cuda.o and
2) try this makefile:
matrix_cuda.o: matrix_cuda.cu
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works,
3) try this:
g++ -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o -L/usr/local/cuda-7.5/lib64 -I/usr/local/cuda-7.5/include -lopenblas -lpthread -lcudart -lcublas -fopenmp -O3 -Wextra -std=c++11
If that works, remove test and
4) try this makefile:
test: matrix_cuda.o
g++ -o test matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o -L/usr/local/cuda-7.5/lib64 -I/usr/local/cuda-7.5/include -lopenblas -lpthread -lcudart -lcublas -fopenmp -O3 -Wextra -std=c++11
matrix_cuda.o: matrix_cuda.cu
nvcc -std=c++11 -c -arch=sm_20 matrix_cuda.cu
If that works, remove test and matrix_cuda.o and
5) try that makefile again.
If that works, there are further refinements we can make.
Also your first make rule corresponds to compiling the object file matrix_cuda.o. The all make rule should come first since the first rule in the make file is the one that gets updated first when invoking the command make. GNU Make has great documentation explaining how to make simple to complex makefiles. You can check it out here:
https://www.gnu.org/software/make/manual/make.html.
Also another issue you are going to run into is that in your make recipe for the all rule, you are supposed to be linking together only object files to create the final executable. However you are trying to include matrix_blas.cpp alg.cpp test.cpp in this linking step. Instead of .cpp versions of these files they need to be .o versions (the compiled objects). Make can generate these object files for you. You just need to have a make rule and recipe for each one. For example:
matrix_blas.o: matrix_blas.cpp
$(CC) $(CXXFLAGS) -c matrix_blas.cpp -o matrix_blas.o
I want to add some commentary on this Makefile for future reference and better automation :
1. NVCC=nvcc environment variable is superfluous. There is only one compiler for NVIDIA GPUs and you would nonetheless have to change a lot of flags to compile for other architectures like AMD.
-arch=native is better suited if you want to deploy your code on multiple machines with GPUs having different architectures
-dc is the flag for separate compilation. The architecture must be specified before -dc see (with a generic Makefile): https://developer.nvidia.com/blog/separate-compilation-linking-cuda-device-code/
You should add automatic rule to avoid these typos errors :
%.o: %.cu
nvcc -dc $(CUDAFLAGS) $< -o $#
The Makefile will look for all dependencies ending by .o. If it needs to build one, it looks if it has the corresponding .cu file. I would actually remove the -dc from flags and be explicit here that I want to build object files.
$# is the name of the rule target. $< is the first prerequisite. Only one file at a time can be passed to nvcc with the -dc flag, so here $< is better than $^.
You may add the name of the executable in a variable so that you delete the same executable that you generated (and facilitate name change).
I added a .PHONY rule. This only removes the confusion that happens whenever someone writes a file named clean in the directory.
The Makefile can not differenciate between the file and the make clean rule.
CC=g++
CXXFLAGS= -fopenmp -O3 -Wextra -std=c++11
CUDAFLAGS= -std=c++11 -arch=sm_20
LIBS= -lopenblas -lpthread -lcudart -lcublas
LIBDIRS=-L/usr/local/cuda-7.5/lib64
INCDIRS=-I/usr/local/cuda-7.5/include
PROGRAM= test
%.o: %.cu
nvcc -dc $(CUDAFLAGS) $< -o $#
all: matrix_cuda.o
$(CC) -o $(PROGRAM) matrix_blas.cpp alg.cpp test.cpp matrix_cuda.o $(LIBDIRS) $(INCDIRS) $(LIBS) $(CXXFLAGS)
.PHONY: clean
clean:
rm -rf $(PROGRAM) *.o

Clang error while creating shared library

I want to compile a shared library on MBP and based on the advise given here, I have switched to clang (from gcc) to create the shared library. My makefile is:
CC = clang
CFLAGS = -c -fPIC -Wall -O3 -lpthread -g
BaseDir = /Users/admin/Prog/
Include = -I$(BaseDir)UMFPACK/Include -I$(BaseDir)AMD/Include -I$(BaseDir)SuiteSparse_config
Lib = -L$(BaseDir)UMFPACK/Lib -L$(BaseDir)AMD/Lib -L$(BaseDir)GotoBLAS2 -L$(BaseDir)SuiteSparse_config
AddFiles = -lumfpack -lamd -lgoto2 -lsuitesparseconfig
StaticLibs = $(BaseDir)GotoBLAS2/libgoto2.a $(BaseDir)UMFPACK/Lib/libumfpack.a $(BaseDir)AMD/Lib/libamd.a $(BaseDir)SuiteSparse_config/libsuitesparseconfig.a
all: TDS.o TDSJac.o ExtraRoutines.o CalcVFC.o TDS.h
$(CC) $(Include) $(Lib) $(AddFiles) -dynamiclib -lpthread -o libTDS.so $^ -lm -g $(StaticLibs)
TDS.o: TDS.c TDS.h
$(CC) $(Include) $(CFLAGS) $^
TDSJac.o: TDSJac.c TDS.h
$(CC) $(CFLAGS) $^
ExtraRoutines.o: ExtraRoutines.c TDS.h
$(CC) $(CFLAGS) $^
CalcVFC.o: CalcVFC.c TDS.h
$(CC) $(CFLAGS) $^
MexFile: TDSGateway.c
mex -g -largeArrayDims -ldl TDSGateway.c
Move:
mv libTDS.so ../../
mv TDSGateway.mexmaci64 ../../
What I do here is:
1) Only compile TDS.c, TDSJac.c, ExtraRoutines.c, and CalcVFC.c to create four corresponding object files.
2) Merging object files and creating a shared library using following command:
clang -I(Some folders) -L(Some folders) -l(Some libraries) -shared -lpthread -o libTDS.so TDS.o TDSJac.o ExtraRoutines.o CalcVFC.o TDS.h -lm -g
clang: error: cannot specify -o when generating multiple output files
As I am absolutely new to clang, I do not know what is wrong with Makefile. (If I replace CC=clang with CC=gcc, everything works good.)
I searched the internet with no success. Manual page of clang says nothing about shared library. I could not even get anything out of clang homepage. It is appreciated if help me to work around this problem.
Thanks for your help in advance.
I had yesterday almost the same problem.
But i never used cmake. I'm using an own makefile system of my company, so I just can tell you, what fixed the problem for me so far.
Clang has still some trouble with giving you the right hints on errorcase.
The linking error was:
/usr/bin/ld: /usr/lib/crt1.o: relocation R_X86_64_32 against `_DYNAMIC' can not be used when making a shared object; recompile with -fPIC
I solved the problem as I figgered out, that the -shared Parameter has to be behind the -o X.o parameters. As I see this is not made in your case, too. You should try that first.
In our case I also had to parse the LFlags with -WL, or -L, (afaik it doesn't matter which one you take but I read about a clang bug in relation to -Wl,).
But idk in how far you have to parse LFlags or not, when using cmake.
You've listed headers (TDS.h) as dependencies, which is fine, but you've then used $^ as inputs, which includes all dependencies. You should not list a header as an input. It should not be on the command-line at all, and in clang this is actually an error.
The error message is obscure but easy to resolve. You have 2 choices:
Be explicit instead of using $^. You could use a variable for inputs and another for dependencies, e.g.; or
Use intermediate .o files instead of .c files as inputs to a .so. The *.o files can depend on any .h they include.

Resources