This question already has answers here:
What does this GCC error "... relocation truncated to fit..." mean?
(11 answers)
gfortran for dummies: What does mcmodel=medium do exactly?
(2 answers)
Closed 3 years ago.
The makefile I attach comes from the source directory of a smooth particle hydrodynamics code. When I fix the number of particles to 128**3 particles, my code compiles fine. Now that I need to use 256**3 I get a relocation truncated to fit: R_X86_64_PC32 against symbol ... defined in COMMON section in ....
I have tried several things I found online:
using the set stacksize unlimited command
adding the -mcmodel=large flag
adding the -fPIC flag
none of these seem to work. I am also aware of the https://www.technovelty.org/c/relocation-truncated-to-fit-wtf.html article, but I do not understand what I am supposed to do.
My makefile: (I attach part of it)
include ../makeflags
CPP=g++
CPPFLAGS = $(OPTIONS) -D$(SYS) -mcmodel=large -traceback
.SUFFIXES: .F
OBJ = hydra.o accel.o ahtime.o clist.o cool.o createcool.o dumpdata.o
.f.o:
$(F77) $(FLAGS) -c $<
.F.o:
# if test $(SYS) = ibm ; then \
echo "$(CPP) -P -C $(CPPFLAGS) $< > tmp/$*.f";\
$(CPP) -P -C $(CPPFLAGS) $< > tmp/$*.f;\
echo "$(F77) $(FLAGS) -c tmp/$*.f";\
$(F77) $(FLAGS) -c tmp/$*.f;\
elif test $(SYS) = f2c ; then \
echo "$(CPP) -P -C $(CPPFLAGS) $< > tmp/$*.f";\
$(CPP) -P -C $(CPPFLAGS) $< > tmp/$*.f;\
echo "$(F77) $(FLAGS) -c tmp/$*.f";\
$(F77) $(FLAGS) -c tmp/$*.f;\
else \
echo "$(F77) $(FLAGS) $(CPPFLAGS) -c $<";\
$(F77) $(FLAGS) $(CPPFLAGS) -c $<;\
fi
.c.o:
$(CC) -c $(CPPFLAGS) $(CFLAGS) $<
hydra: tmp $(OBJ)
echo $(FLAGS)
$(F77) -o hydra $(FLAGS) $(OBJ) $(LIBS)
mv hydra $(RUNDIR)
new_options:
touch *.F
make
clean:
/bin/rm -rf *.o tmp
system.o: system.$(SYS)
# if test $(SYS) = f2c ; then \
cp system.f2c system.c; \
$(CC) -c $(CPPFLAGS) $(CFLAGS) system.c; \
else \
cp system.$(SYS) system.f; \
$(F77) $(FLAGS) -c system.f; \
fi
tmp:
# test -d $# || mkdir $#
# for i in `ls *.inc` ; do \
(cd tmp ; ln -s ../$$i $$i ) ; \
done
My flags file: (I attach part of it)
SHELL = /bin/sh
# set SYS to one of: sun, dec, cray, sgi, ibm, hpux, f2c, g77
SYS = g77
# choose appropriate names for compilers
F77 = /usr/bin/f77
CC = cc
CPP = /lib/cpp
# compilation flags for linux box
FLAGS= -O2
FLAGS= -O2 -fomit-frame-pointer -m486
FLAGS= -Wall -g
FLAGS= -mcmodel=large
# For cosmic test use
UNITS_OPTIONS =
OTHER_OPTIONS =
OPTIONS = $(FORCE_OPTIONS) $(UNITS_OPTIONS) $(OTHER_OPTIONS)
I understand this is some memory problem, which, for some reason is not resolved with the options I have described above. Please bare in mind I cannot mess with the variable definitions in the code (e.g. change COMMON blocks etc.), because they are linked to many programs and this will cause an overall failure of compilation. The exact error I am receiving is:
/home/user/Downloads/Stage/hydra4.0/src/hydra.F:1:(.text+0x14): relocation truncated to fit: R_X86_64_PC32 against symbol `param_' defined in COMMON section in hydra.o
for many component programs, not only for hydra.o.
After 3 months of looking into this problem, I solved it by adding -mcmodel=medium.
Related
I have a project that I want to build a shared library for it. The following Makefile works:
libfastpd.so: fastpd.cpp
$(CXX) -std=c++11 -fPIC -c fastpd.cpp -o fastpd.o
$(CXX) -std=c++11 -fPIC -c graph.cpp -o graph.o
$(CXX) -std=c++11 -fPIC -c LinkedBlockList.cpp -o LinkedBlockList.o
$(CXX) -std=c++11 -fPIC -c maxflow.cpp -o maxflow.o
$(CXX) -std=c++11 -shared -Wl,-soname,libfastpd.so -o libfastpd.so fastpd.o graph.o LinkedBlockList.o maxflow.o
clean:
rm *.o *.so
Then I came across this recipe in Cogswell et al.'s C++ Cookbook: https://www.oreilly.com/library/view/c-cookbook/0596007612/ch01s18.html
and decided to improve my Makefile based on that:
# Specify extensions of files to delete when cleaning
CLEANEXTS = o so
# Specify the source files, the target files,
# and the install directory
SOURCES = fastpd.cpp graph.cpp LinkedBlockList.cpp maxflow.cpp
OUTPUTFILE = libfastpd.so
INSTALLDIR = ./
.PHONY: all
all: $(OUTPUTFILE)
# Build lib*.so from all the *.o;
# subst is the search-and-replace
# function demonstrated in Recipe 1.16
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES))
$(CXX) -shared -fPIC $(LDFLAGS) -o $# $^
.PHONY: install
install:
mkdir -p $(INSTALLDIR)
cp -p $(OUTPUTFILE) $(INSTALLDIR)
.PHONY: clean
clean:
for file in $(CLEANEXTS); do rm -f *.$$file; done
# Generate dependencies of .ccp files on .hpp files
include $(subst .cpp,.d,$(SOURCES))
%.d: %.cpp
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
Running this file I obtained the following error:
/usr/bin/ld: fastpd.o: relocation R_X86_64_32 against `.rodata' can
not be used when making a shared object; recompile with -fPIC
fastpd.o: error adding symbols: Bad value
Checking the terminal output, I observed that the following commands were executed:
g++ -c -o fastpd.o fastpd.cpp
g++ -c -o graph.o graph.cpp
g++ -c -o LinkedBlockList.o LinkedBlockList.cpp
g++ -c -o maxflow.o maxflow.cpp
No -fPIC!
My question is: Which lines of the Makefile execute these commands and how to add -fPIC to them?
Any references to good ressources to understand the entire Makefile above would be very much appreciated as well!
Thank you very much in advance for your help!
Which lines of the Makefile execute these commands... ?
The short answer is none. The rule...
$(OUTPUTFILE): $(subst .cpp,.o,$(SOURCES))
$(CXX) -shared -fPIC $(LDFLAGS) -o $# $^
only specifies the link time dependencies and command. The -fPIC option needs to be specified when you compile the source file but you haven't provided any rule to build a .o from a .cpp so make falls back on its implicit rule which (for the purposes of this example) is essentially...
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
So the obvious solution is to add -fPIC to CXXFLAGS...
CXXFLAGS += -fPIC
I am doing a simple Interpreter using bison and lex. This is my make file content.
#
# makefile for ccalc
#
OBJS += mylang.o SM.o lex.o parse.o
# rules
%.c: %.y
bison -o $(#:%.o=%.d) $<
%.c: %.l
flex -o$(#:%.o=%.d) -i $<
# dependencies
mylang: mylang.yy.tab.c lex.c $(OBJS)
#echo g++ -Os -std=c++0x -omylang $(OBJS)
#g++ -Os -std=c++0x -omylang $(OBJS)
#echo ' '
# source
mylang.o: mylang.cpp
SM.o: SM.cpp SM.h
lex.o: lex.c
parse.o: mylang.yy.tab.c
mylang.yy.tab.c: mylang.yy
lex.c: mylang.ll
When run this make file, The command running as
g++ -c -o SM.o SM.cpp
But I want to run as,
g++ -Os -std=c++0x -c -o SM.o SM.cpp
What Should I change in my make file to run with c++0x Compiler Version.
Set CXXFLAGS flags accordingly:
CXXFLAGS="-Os -std=c++0"
make uses internal defaults rule to compile
c++ files to .o files. You can display them with make -p.
The rules in your case are
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.cpp = $(COMPILE.cc)
%.o: %.cpp
# recipe to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
I'm trying to compile a simple program from the terminal that utilizes the condition_variable class. Upon building, I get the following error:
This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
In researching this error here, I added the necessary flag to my make file, but I'm still getting the same error.
Here is my makefile:
CXX= g++ $(CCFLAGS)
MAIN= main.o
DATACLASS= dataclass.o
OBJS = $(MAIN) $(DATACLASS)
LIBS= -pthread
CCFLAGS= -g -std=c++11
all: main
main: $(MAIN) $(DATACLASS)
$(CXX) -o main $(MAIN) $(DATACLASS) $(LIBS)
dataclass: $(DATACLASS)
$(CXX) -o dataclass $(DATACLASS) $(LIBS)
clean:
rm -f $(OBJS) $(OBJS:.o=.d)
realclean:
rm -f $(OBJS) $(OBJS:.o=.d) main
%.d: %.cc
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $# : /g'\'' > $#; \
[ -s $# ] || rm -f $#'
include $(OBJS:.o=.d)
I'm sure I'm missing something small and stupid as I'm new to makefiles, but any help would be greatly appreciated.
Rewrite CXX to CXX = g++
Change CCFLAGS to CXXFLAGS = -g -std=c++11, and
Rewrite your rules to $(CXX) $(CXXFLAGS) ....
$(CXX) $(CXXFLAGS) will then be replaced with g++ -g -std=c++11. This is more of a standard method for defining a makefile. Here is a snippet of the resulting makefile.
CXX = g++
MAIN = main.o
DATACLASS = dataclass.o
OBJS = $(MAIN) $(DATACLASS)
LIBS = -pthread
CXXFLAGS = -g -std=c++11
all: main
main: $(OBJS)
$(CXX) $(CXXFLAGS) $? -o $# $(LIBS)
As a side note, are you sure this rule should be defined as such?
dataclass: $(DATACLASS)
$(CXX) $(CXXFLAGS) $? -o $# $(LIBS)
Should the target not be dataclass.o or $(DATACLASS) and the prerequisite some other file?
Note: I've also included some make automatic variables to tidy up the makefile rules.
$? - is replaced by all prerequisites
$# - is replaced by the target name
I am having an issue defining a prerequisites for my targets while using file lists in variables the problem is as follows:
in my makefile:
... some basic defines
SOURCES=HelloC.cpp \
HelloS.cpp \
HelloI.cpp \
main.cpp
SOURCES_CLIENT=Hello_Client_impl.cpp \
HelloC.cpp
OBJECTS_SERVER_DIR=obj_s/
OBJECTS_CLIENT_DIR=obj_c/
OBJECTS_SERVER=$(addprefix $(OBJECTS_SERVER_DIR),$(SOURCES:.cpp=.o))
OBJECTS_CLIENT=$(addprefix $(OBJECTS_CLIENT_DIR),$(SOURCES_CLIENT:.cpp=.o))
EXECUTABLE_SERVER=server
EXECUTABLE_CLIENT=client
all: dirs server_exe client_exe
dirs:
#echo create dirs
$(CREATE_DIR) $(OBJECTS_SERVER_DIR)
$(CREATE_DIR) $(OBJECTS_CLIENT_DIR)
server_exe: $(EXECUTABLE_SERVER)
client_exe: $(EXECUTABLE_CLIENT)
$(EXECUTABLE_SERVER): $(OBJECTS_SERVER)
$(CXX) $^ $(LFLAGS) $(LIBS) -o $#
$(EXECUTABLE_CLIENT): $(OBJECTS_CLIENT)
$(CXX) $^ $(LFLAGS) $(LIBS) -o $#
# problematic line 1
$(OBJECTS_SERVER): $(SOURCES)
$(CXX) -c $(CPPFLAGS) -o $# $<
# problematic line 2
$(OBJECTS_CLIENT): %.o : %.cpp
$(CXX) -c $(CPPFLAGS) -o $# $<
Running it (as dry run) I will get:
$ make -n
echo create dirs
mkdir -p obj_s/
mkdir -p obj_c/
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/HelloC.o HelloC.cpp
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/HelloS.o HelloC.cpp
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/HelloI.o HelloC.cpp
g++ -c -Wall -I. -I/usr/include/ -I/usr/include/orbsvcs/ -I/usr/include/tao/ -I/usr/include/tao/PortableServer/ -o obj_s/main.o HelloC.cpp
g++ obj_s/HelloC.o obj_s/HelloS.o obj_s/HelloI.o obj_s/main.o -L/usr/lib64/ -lTAO_PortableServer -lTAO_AnyTypeCode -lTAO -lACE -o server
make: *** No rule to make target `obj_c/Hello_Client_impl.cpp', needed by `obj_c/Hello_Client_impl.o'. Stop.
problematic line 1 will not expand and will always keep the first source file (HelloC.cpp) as a parameter while the second one is defined with prefix. How can I handle this so that it compiles? I would like to have source files in root dir and object files in obj_c and obj_s directories
EDIT: I originally answered the wrong question in haste, sorry about that. Anyway, the static pattern rule is the way to go, but you have to factor in the prefix. Instead of
$(OBJECTS_CLIENT): %.o : %.cpp
Use
$(OBJECTS_CLIENT): $(OBJECTS_CLIENT_DIR)%.o : %.cpp
I have the following file from the PARSEC opensource benchmarks, and I want to be able to profile it using gcc. yet as u know i need to raise the -pg flags. yet i am having difficulties doing so. i tried to use a regular g++ -pg -o files.cpp yet it didnt work. i also tried to modify the makefile that infront of the -o i placed a -pg yet it also gave huge errors. So now i am stuck, either I did something wrong or the -pg flags require something special...yet the makefile when executed alone gave me an output which i tested by running and it was successfull! so i am sure the source code is accepted by my compiler
# Makefile for parallel simulated annealer
PREFIX=${PARSECDIR}/pkgs/kernels/canneal/inst/${PARSECPLAT}
TARGET=canneal
LIBS:=$(LIBS) -lm
ifdef version
ifeq "$(version)" "pthreads"
CXXFLAGS+=-DENABLE_THREADS -pthread
endif
endif
all:
$(CXX) $(CXXFLAGS) annealer_thread.cpp -c -o annealer_thread.o
$(CXX) $(CXXFLAGS) rng.cpp -c -o rng.o
$(CXX) $(CXXFLAGS) netlist.cpp -c -o netlist.o
$(CXX) $(CXXFLAGS) main.cpp -c -o main.o
$(CXX) $(CXXFLAGS) netlist_elem.cpp -c -o netlist_elem.o
$(CXX) $(CXXFLAGS) $(LDFLAGS) *.o $(LIBS) -o $(TARGET)
clean:
rm -f *.o $(TARGET)
install:
mkdir -p $(PREFIX)/bin
cp -f $(TARGET) $(PREFIX)/bin/$(TARGET)
Try adding this near the top of the file:
CXXFLAGS+= -pg