When linking some object files together I get a bunch of errors like:
obj-ia32/ShadowRoutine.o: In function `InitializeMap(unsigned int*)':
ShadowRoutine.cpp:(.text+0x0): multiple definition of `InitializeMap(unsigned int*)'
obj-ia32/ShadowRoutine.o:ShadowRoutine.cpp:(.text+0x0): first defined here
with compilation and linking commands of:
g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
-DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX -I../../../source/include/pin \
-I../../../source/include/pin/gen -I../../../extras/components/include \
-I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
-fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
-Wno-unused-function -I. -Ishadow-memory -m32 -c \
-o obj-ia32/ShadowRoutine.o ShadowRoutine.cpp
g++ -DBIGARRAY_MULTIPLIER=1 -Wall -Wno-unknown-pragmas -fno-stack-protector \
-DTARGET_IA32 -DHOST_IA32 -DTARGET_LINUX -I../../../source/include/pin \
-I../../../source/include/pin/gen -I../../../extras/components/include \
-I../../../extras/xed-ia32/include -I../../../source/tools/InstLib -O3 \
-fomit-frame-pointer -fno-strict-aliasing -Wno-unused-variable \
-Wno-unused-function -I. -Ishadow-memory -m32 -c \
-o obj-ia32/Jikes.o Jikes.cpp
g++ -shared -Wl,--hash-style=sysv -Wl,-Bsymbolic \
-Wl,--version-script=../../../source/include/pin/pintool.ver \
-m32 -o obj-ia32/Jikes.so obj-ia32/ClientReq.o obj-ia32/Server.o \
obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
obj-ia32/Jikes.o obj-ia32/ClientReq.o obj-ia32/Server.o \
obj-ia32/ShadowRoutine.o obj-ia32/FncnMap.o obj-ia32/Trace.o \
-L../../../ia32/lib -L../../../ia32/lib-ext -L../../../ia32/runtime/glibc \
-L../../../extras/xed-ia32/lib \
-L/home/karl/r/git/pin/source/tools/Jikes/zmq/inst/lib \
-lpin -lxed -lpindwarf -ldl -lzmq
The only two object files with InitializeMap are Jikes.o and ShadowRoutine.o:
$ nm obj-ia32/Jikes.o | grep InitializeMap
U _Z13InitializeMapPj
$ nm obj-ia32/ShadowRoutine.o | grep InitializeMap
00000000 T _Z13InitializeMapPj
$ nm obj-ia32/* | grep InitializeMap
U _Z13InitializeMapPj
00000000 T _Z13InitializeMapPj
So why am I getting "multiple definitions of InitializeMap" if it's only "defined" in one object file and "undefined" in the only other object file that required it using extern?
This is what the declarations, definitions, and uses look like:
$ grep -r InitializeMap *
Jikes.cpp: if (rtn_name == "sysInitializeMap") { RTN_INSERT_1(InitializeMap);
Binary file obj-ia32/Jikes.o matches
Binary file obj-ia32/ShadowRoutine.o matches
ShadowRoutine.cpp:VOID InitializeMap(ADDRINT *smID) { init_map(*(int*)smID); }
ShadowRoutine.hpp:VOID InitializeMap(ADDRINT *smID);
where both the cpp files #include "ShadowRoutine.hpp".
EDIT: My question is why does the linker command (the third g++ command in the second code snippet above) not work even though nm says that the function is only defined in the text of ShadowRoutine.o and undefined in Jikes.o?
You have the file obj-ia32/ShadowRoutine.o listed twice in your link command.
Related
This is my makefile in linux
.SILENT:
.SUFFIXES: .cpp
FLAGS_CC = -c -fPIC -DUNIX -DLINUX -D_HNAREL_=500 -D_TARGET__REL=0 -D_TARGET__DEBUG=1 -D_ILS_MACROS -I$(cer_incl)
FLAGS_CPP = -c -Wno-deprecated -fPIC -frtti -finline-functions -DUNIX -DLINUX -D_HNAREL_=500 -D_TARGET__REL=0 -D_TARGET__DEBUG=1 -D_ILS_MACROS -I$(cer_incl)
FLAGS_LINK = -m32 -fPIC -lm -lc -lrt -lpthread -ldl
FLAGS_LINKSHR = -m32 -lm -lc -shared -Wl,-no-undefined -lrt -lpthread -ldl
CC = gcc $(FLAGS_CC) $(__define) $(__build)
CPP = g++ $(FLAGS_CPP) $(__define) $(__build)
LINK = g++ $(FLAGS_LINK)
LINKSHR = g++ $(FLAGS_LINKSHR)
PRINT = echo
##
## The following environment variables are defined for your convenience.
##-----
## __srcdir - Project directory that contains the makefile and source code.
## __objdir - Project subdirectory that stores objects for the given platform
## and target combination.
## __libdir - Public directory that contains objects and shareable libraries.
## __exedir - Public directory that contains executables.
##-----
## Please do not delete the following line!
###makefile###
###makedep###
#my_project.o
FLAGS__MY_PROJECT =
DEFINES__MY_PROJECT =
my_project.o: $(__objdir)/my_project.o
$(__objdir)/my_project.o: \
my_project.cpp \
$(cer_incl)/srvimpl.h \
$(PRINT) "compiling - my_project.cpp"
[[ -d $(__objdir) ]] || mkdir -p $(__objdir)
$(CPP) $(FLAGS__MY_PROJECT) $(DEFINES__MY_PROJECT) -o $(__objdir)/my_project.o my_project.cpp
#aps_s200061.o
FLAGS__APS_S200061 =
DEFINES__APS_S200061 =
aps_s200061.o: $(__objdir)/aps_s200061.o
$(__objdir)/aps_s200061.o: \
aps_s200061.cpp \
aps_s200061.h \
$(cer_incl)/srvimpl.h \
$(PRINT) "compiling - aps_s200061.cpp"
[[ -d $(__objdir) ]] || mkdir -p $(__objdir)
$(CPP) $(FLAGS__APS_S200061) $(DEFINES__APS_S200061) -o $(__objdir)/aps_s200061.o aps_s200061.cpp
###makedep###
FLAGS_CPP += -D__RHEL6
FLAGS__APS_S200061 =
objects: my_project.o aps_s200061.o
my_project : objects
$(PRINT) "creating - my_project "
$(LINKSHR) \
-Wl,--version-script=$(__srcdir)/my_project.emap \
-o $(__objdir)/my_project \
$(__objdir)/my_project.o \
$(__objdir)/aps_s200061.o \
-Wl,--start-group \
-L$(__libdir) -lapsobj -lcernobj -lcontainerobj -lstringobj -li18n_common -lmsgutilobj -lmftmiscobj -lsrvcoreobj -lcrmobj -lthreadobj \
-Wl,--whole-archive -lsrvobj -Wl,--no-whole-archive \
-Wl,--end-group \
-L$(__exedir) -ldb -ldps -lsrv -lsec \
-lcclora -lreg -lmsgapi -ldate \
-llogical -lsrvcore -lcrm
copy:
$(PRINT) "copying - my_project"
cp $(__objdir)/my_project $(__exedir)
it: my_project copy
# shr:my_project
I want to remove the command cp $(__objdir)/my_project $(__exedir) from the above file.
When I try removing the line manually in a text editor and save it , the make file doesn't throw any errors.
But if I try removing the line programmatically , we get make: *** No rule to make target my_project.o', needed by objects'. Stop.
Sequence of commands we use is :
'makedep'
'make -f ${PWD##*/}.linux -r __target=rel _define="-D_TARGET=_TARGET__REL " __srcdir=$PWD __objdir=$PWD/linuxx86-64 __libdir=$abc_lib_rel __exedir=$abc_exe_rel __build="-O3" it'
I can compile all examples of boost:stacktrace. Here is my bash script:
#!/bin/bash
export CXX=~/x-tools/x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-g++
export BOOST_INCLUDE=$HOME/x-libs/$($CXX -dumpmachine)/include
export BOOST_LIB=$HOME/x-libs/$($CXX -dumpmachine)/lib
export BOOST_SUFFIX="mt-d"
(ls $BOOST_LIB/*$BOOST_SUFFIX.a | tr "\n" "\0" | xargs -0 -n 1 basename | while read A; do B=-l$(echo $A | sed -e 's/^lib//' | sed -e 's/\.a//'); echo $B; done;) | tr "\n" " " > $BOOST_LIB/list_boost.txt
export BOOST_LIBS="cat $BOOST_LIB/list_boost.txt"
export EXECUTABLE_SUFFIX=""
$CXX -w -g3 -o assert_handler-$($CXX -dumpmachine)$EXECUTABLE_SUFFIX assert_handler.cpp -std=c++11 -static -I$BOOST_INCLUDE -L$BOOST_LIB $(eval $BOOST_LIBS) -ldl
$CXX -w -g3 -o debug_function-$($CXX -dumpmachine)$EXECUTABLE_SUFFIX debug_function.cpp -std=c++11 -static -I$BOOST_INCLUDE -L$BOOST_LIB $(eval $BOOST_LIBS) -ldl
$CXX -w -g3 -o terminate_handler-$($CXX -dumpmachine)$EXECUTABLE_SUFFIX terminate_handler.cpp -std=c++11 -static -I$BOOST_INCLUDE -L$BOOST_LIB $(eval $BOOST_LIBS) -ldl -lrt -lpthread
$CXX -w -g3 -o throwing_st-$($CXX -dumpmachine)$EXECUTABLE_SUFFIX throwing_st.cpp -std=c++11 -static -I$BOOST_INCLUDE -L$BOOST_LIB $(eval $BOOST_LIBS) -ldl
$CXX -w -g3 -o trace_addresses-$($CXX -dumpmachine)$EXECUTABLE_SUFFIX trace_addresses.cpp -std=c++11 -static -I$BOOST_INCLUDE -L$BOOST_LIB $(eval $BOOST_LIBS)
$CXX -w -g3 -o user_config-$($CXX -dumpmachine)$EXECUTABLE_SUFFIX user_config.cpp -std=c++11 -static -I$BOOST_INCLUDE -L$BOOST_LIB $(eval $BOOST_LIBS) -ldl
The generated boost list looks like this:
-lboost_atomic-mt-d -lboost_chrono-mt-d -lboost_container-mt-d -lboost_context-mt-d -lboost_coroutine-mt-d -lboost_date_time-mt-d -lboost_exception-mt-d -lboost_fiber-mt-d -lboost_filesystem-mt-d -lboost_graph-mt-d -lboost_iostreams-mt-d -lboost_locale-mt-d -lboost_log-mt-d -lboost_log_setup-mt-d -lboost_math_c99f-mt-d -lboost_math_c99l-mt-d -lboost_math_c99-mt-d -lboost_math_tr1f-mt-d -lboost_math_tr1l-mt-d -lboost_math_tr1-mt-d -lboost_prg_exec_monitor-mt-d -lboost_program_options-mt-d -lboost_random-mt-d -lboost_regex-mt-d -lboost_serialization-mt-d -lboost_signals-mt-d -lboost_stacktrace_addr2line-mt-d -lboost_stacktrace_basic-mt-d -lboost_stacktrace_noop-mt-d -lboost_system-mt-d -lboost_test_exec_monitor-mt-d -lboost_thread-mt-d -lboost_timer-mt-d -lboost_type_erasure-mt-d -lboost_unit_test_framework-mt-d -lboost_wave-mt-d -lboost_wserialization-mt-d
If I run an example it prints pointers:
./assert_handler-x86_64-unknown-linux-gnu
Expression 'i < N' is false in function 'T& boost::array<T, N>::operator[](boost::array<T, N>::size_type) [with T = int; long unsigned int N = 5ul; boost::array<T, N>::reference = int&; boost::array<T, N>::size_type = long unsigned int]': out of range.
Backtrace:
0# 0x00000000004019B2
1# 0x0000000000401B39
2# 0x0000000000400E3B
3# 0x0000000000400E6B
4# 0x0000000000400E44
5# 0x0000000000400E6B
6# 0x0000000000400E7C
7# 0x000000000045BF2B
8# 0x000000000045C1D1
9# 0x0000000000400CEA
Have I miss something?
Works for me now.
boost::stacktrace needs libbacktrace to print more than pointers
the compiler needs -lbacktrace -DBOOST_STACKTRACE_USE_BACKTRACE
The full line for compilation in the upper bash script example is then:
$CXX -w -g3 -o assert_handler-$($CXX -dumpmachine)$EXECUTABLE_SUFFIX assert_handler.cpp -std=c++11 -static -I$BOOST_INCLUDE -L$BOOST_LIB $(eval $BOOST_LIBS) -ldl -lbacktrace -DBOOST_STACKTRACE_USE_BACKTRACE
boost::stacktrace is new in the current Boost v1.65.1 and Debian Stretch that I use has only v1.62.0 and doesn't provide libbacktrace. So I had to download/compile these two on my own.
I cross compile for x86_64-unknown-linux-gnu and i686-w64-mingw32. It works for Linux but the mingw executables print almost nothing. I will investigate that and maybe post my results later here.
prefix=#prefix#
exec_prefix=#exec_prefix#
bindir=#bindir#
CFLAGS = -pipe -O2 -g `freetype-config --cflags` -c -Wall -Wno-multichar `cat #top_srcdir#/madlax.specs`
CPPFLAGS= $(CFLAGS) -Woverloaded-virtual -Wnon-virtual-dtor
CC = #CC#
EXE = jpegtranslator
MLXLIBDIR = #top_srcdir#/src/kits/objs
SUBDIR = libjpeg
SRC := $(SUBDIR)/jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jcdiffct.c \
jchuff.c jcinit.c jclhuff.c jclossls.c jclossy.c jcmainct.c jcmarker.c jcmaster.c jcodec.c \
jcomapi.c jcparam.c jcphuff.c jcpred.c jcprepct.c jcsample.c jcscale.c jcshuff.c jctrans.c \
jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jddiffct.c jdhuff.c \
jdinput.c jdlhuff.c jdlossls.c jdlossy.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
jdpostct.c jdpred.c jdsample.c jdscale.c jdshuff.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jmemmgr.c jmemnobs.c jquant1.c jquant2.c \
jutils.c
OBJS = be_jdatadst.o be_jdatasrc.o be_jerror.o JPEGTranslator.o $(SRC)
OBJDIR := objs
include #top_srcdir#/makefile.rules
all : $(OBJDIR) $(OBJDIR)/$(EXE)
$(OBJDIR):
mkdir $(OBJDIR) -C $(SUBDIR)
The main part of concern is the $(OBJDIR) -C $(SUBDIR), because I don't really know if I also need the -I$(SUBDIR) or the -L$(SUBDIR), or if I just use -ljpeg
First of all the -l option (lower-case L) is for linking with a library, and -L is for adding a path to the linkers library-search-path-list.
And yes you need -L if you want to link with a library in a non-standard location using -l.
You can also skip both the -L and -l options, and provide the full path to the library instead.
I need to compile a C++ project which is going to use external libraries and headers from the project for linear programming COIN-OR. It contains two .cpp files. The main file, main-farmer, depends on pm.h.
pm.h has all the include lines main-farmer needs to use to call in the COIN-OR functions. This is is the code of pm.h:
#include "ClpSimplex.hpp"
#include "CoinHelperFunctions.hpp"
#include "CoinTime.hpp"
#include "CoinBuild.hpp"
#include "CoinModel.hpp"
I have a makefile provided by my teacher and modified to fit my own needs, but whenever I try to compile the project by running my Makefile I get the same error:
In file included from main-farmer.cpp:5:0: pm.h:14:26: fatal error:
ClpSimplex.hpp: No such file or directory compilation terminated.
make: *** [main-farmer.o] Error 1
This is the Makefile:
#
P=farmer
#
EXE=$(P)
OBJS=main-farmer.o model-farmer.o param-farmer.o pm.h
ADDLIBS=-D.
ADDINCFLAGS=-I.
SRCDIR=~/coin-projects
##########
CXX=g++
CXXFLAGS=-O3 -fomit-frame-pointer -pipe -DNDEBUG -pedantic-errors -Wimplicit -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion
CXXLINKFLAGS=-Wl,--rpath -Wl,/installed/CoinAll/lib
CC=gcc
CFLAGS=-03 -fomit-frame-pointer -pipe -DNDEBUG -pedantic-errors -Wimplicit -Wparentheses -Wsequence-point -Wreturn-type -Wcast-qual -Wall
COININCDIR=/installed/CoinAll/include/coin
# COIN-OR libs
COINLIBDIR=/installed/CoinAll/lib
# Clp
LIBS=-L$(COINLIBDIR) -lCbc -lCgl -lOsiClp -lOsi -lClp -lCoinUtils -lm \
`cat $(COINLIBDIR)/cgl_addlibs.txt` \
`cat $(COINLIBDIR)/clp_addlibs.txt` \
`cat $(COINLIBDIR)/coinutils_addlibs.txt`
CLEANFILES=\
addBits.o addBits \
addColumns.o addColumns \
addRows.o addRows \
decompose.o decompose \
defaults.o defaults \
driver2.o driver2 \
driver.o driver \
driverC.o driverC \
dualCuts.o dualCuts \
ekk.o ekk \
ekk_interface.o ekk_interface \
hello.o hello \
makeDual.o makeDual \
minimum.o minimum \
network.o network \
piece.o piece \
rowColumn.o rowColumn \
sprint2.o sprint2 \
sprint.o sprint \
testBarrier.o testBarrier \
testBasis.o testBasis \
testGub2.o testGub2 \
testGub.o testGub \
testQP.o testQP \
useVolume.o useVolume
# Part 3
#
all: $(EXE)
.SUFFIXES: .cpp .c .o .obj
$(EXE): $(OBJS)
bla=;
for file in $(OBJS); do bla="$$bla `$(CYGPATH_W) $$file`"; done; \
$(CXX) $(CXXLINKFLAGS) $(CXXFLAGS) -o $# $$bla $(ADDLIBS) $(LIBS)
####
########
############
########
####
clean:
rm -rf $(CLEANFILES)
.cpp.o:
$(CXX) $(CXXFLAGS) $(INCL) -c -o $# `test -f '$<' || echo '$(SRCDIR)/'`$<
.cpp.obj:
$(CXX) $(CXXFLAGS) $(INCL) -c -o $# `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(SRCDIR)/$<'; fi`
.c.o:
$(CC) $(CFLAGS) $(INCL) -c -o $# `test -f '$<' || echo '$(SRCDIR)/'`$<
.c.obj:
$(CC) $(CFLAGS) $(INCL) -c -o $# `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(SRCDIR)/$<'; fi`
Note: ClpSimplex.hpp lives in the directory specified as COININCDIR.
Your Makefile defines COININCDIR which probably points to the parent directory of your .hpp headers. Those need to be found by the compiler, and as the variable is not used, it explains why they are not found.
If you add -I$(COININCDIR) to CXXFLAGS, the compiler will be able to locate them.
This is my makefile :
PROGRAM = mf2005-GPU.f
# Define the Fortran compile flags
F90FLAGS= -g -fopenmp
F90= gfortran
# Define the C compile flags
# -D_UF defines UNIX naming conventions for mixed language compilation.
CFLAGS= -D_UF -O3
CC= gcc
CPPFLAGS= -Dcpp_variable
CXX= g++
# Define GMG objects
#
GMG = r_vector.o\
solvers.o\
ccfd.o\
mf2kgmg.o\
# Define the libraries
SYSLIBS= -lc
USRLIB =
CUDA_LIB64=/cm/shared/apps/cuda40/toolkit/4.0.17/lib64/
LFLAGS = -L$(CUDA_LIB64) -lcuda -lcudart -lcusparse -lcublas -lpthread -lm -lcufft -lcurand -lnpp -lgomp
# Define all object files which make up MODFLOW
OBJECTS = \
dblas.o\
gwf2bas7.o \
de47.o \
dlapak.o\
pcg7.o \
sip7.o \
gmg7.o \
mhc7.o \
gwf2bcf7.o \
gwf2lpf7.o \
gwf2huf7.o \
gwf2rch7.o \
gwfuzfmodule.o \
gwfsfrmodule.o \
gwf2lak7.o \
gwf2sfr7.o \
gwf2uzf1.o \
gwf2gag7.o \
gwf2chd7.o \
gwf2drn7.o \
gwf2drt7.o \
gwf2ets7.o \
gwf2evt7.o \
gwf2fhb7.o \
gwf2ghb7.o \
gwf2hfb7.o \
gwf2ibs7.o \
gwf2res7.o \
gwf2riv7.o \
gwf2str7.o \
gwf2sub7.o \
gwf2swt7.o \
gwf2wel7.o \
hufutl7.o \
obs2bas7.o \
obs2drn7.o \
obs2ghb7.o \
obs2riv7.o \
obs2chd7.o \
obs2str7.o \
parutl7.o \
gwf2mnw17.o \
gwf2mnw27.o \
gwf2mnw2i7.o \
utl7.o \
lmt7.o \
gwf2hydmod7.o \
upcg7.o \
upcgc.o \
upcg7lanczos.o \
upcg7polya.o \
upcg7polyu.o \
mf2005-GPU.o \
# Define Task Function
all: mf2005-GPU
# Define what mf2005
mf2005-GPU: $(OBJECTS) $(GMG)
-$(F90) $(F90FLAGS) -o mf2005-GPU $(OBJECTS) cuda_kernels.o $(GMG) $(USRLIB) $(SYSLIBS) $(LFLAGS)
# Object codes
.f.o:
$(F90) $(F90FLAGS) -c $<
.c.o:
$(CC) $(CFLAGS) -c $<
.cpp.o:
$(CXX) $(CPPFLAGS) -c $<
# end
This is how I compile cuda_kernels.cu
nvcc -c -arch sm_20 -lcuda -lcudart -lcusparse cuda_kernels.cu
This is what I get for errors
upcg7.o: In function `upcg7ar':
/home/zhangmj/MF2005_MAKE/upcg7.f:731: undefined reference to `upcgc7_init_'
upcg7.o: In function `upcg7ap':
/home/zhangmj/MF2005_MAKE/upcg7.f:1272: undefined reference to `upcgc7_'
upcg7.o: In function `upcg7da':
/home/zhangmj/MF2005_MAKE/upcg7.f:1416: undefined reference to `upcgc7_final_'
upcgc.o: In function `UPCGC7':
upcgc.cpp:(.text+0xf6a): undefined reference to `SUPCGILU0A'
collect2: ld returned 1 exit status
make: [mf2005-GPU] Error 1 (ignored)
Following is upcg7.f (this is not my code, I download it from here)
https://github.com/jdhughes-usgs/modflow-2005-upcg/blob/master/code/src/UPCG/upcg7.f
Following is upcgc.cpp and upcgc.h (this is not my code, I download it from here)
https://github.com/jdhughes-usgs/modflow-2005-upcg/blob/master/code/src/UPCG/upcgc.cpp
**My question is **
SUPCGILU0A is the subroutine defined in upcg7.f. And subroutine SUPCGILU0A is called from the C++ program upcgc.cpp.
upcgc7_init, upcgc7 and upcgc7_final are defined in upcgc.cpp, And these three are called from the fortran program upcg7.f.
I understand from my research that these are likely linker issues,or C++ and Fortran need to translate some function/routine from the other, but I cannot figure out what the problem is. Is there anyone out there who might have some insight into what the issue is?
If the upcgc7 routines reside in the C code, they probably do not have the trailing underscore. The best way to deal with this is to make use of the ISO_C_BINDING interface in Fortran and declare the interfaces to these routines.