I'm a newby in cppuTest and actually I'm trying to build the ./examples within the CppuTest root directory. Source and Test files are compiled without problems but I'm stucking on the final linking stage where I get this error:
C:\CppUTest\cpputest-3.7.1\examples>make
compiling AllTests.cpp
compiling CircularBufferTest.cpp
compiling EventDispatcherTest.cpp
compiling HelloTest.cpp
compiling MockDocumentationTest.cpp
compiling PrinterTest.cpp
compiling CircularBuffer.cpp
compiling EventDispatcher.cpp
compiling Printer.cpp
compiling hello.c
Building archive lib/libCppUTestExamples.a
a - objs/ApplicationLib/CircularBuffer.o
a - objs/ApplicationLib/EventDispatcher.o
a - objs/ApplicationLib/Printer.o
a - objs/ApplicationLib/hello.o
Linking CppUTestExamples_tests
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexCreate':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:248: undefined reference to `_imp__pthread_mutex_init'
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexLock':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:255: undefined reference to `_imp__pthread_mutex_lock'
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexUnlock':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:260: undefined reference to `_imp__pthread_mutex_unlock'
../lib/libCppUTest.a(UtestPlatform.cpp.obj): In function `PThreadMutexDestroy':
c:/CppUTest/cpputest-3.7.1/src/Platforms/Gcc/UtestPlatform.cpp:266: undefined reference to `_imp__pthread_mutex_destroy'
collect2.exe: error: ld returned 1 exit status
make: *** [CppUTestExamples_tests] Error 1
I'm using MinGW on Windows 7. The MinGW contains also the pthread.a library. My makefil look as follows:
#---------
#
# CppUTest Examples Makefile
#
#----------
#Set this to # to keep the makefile quiet
ifndef SILENCE
SILENCE = #
endif
#--- Inputs ----#
COMPONENT_NAME = CppUTestExamples
CPPUTEST_HOME = ..
CPPUTEST_USE_EXTENSIONS = Y
CPP_PLATFORM = Gcc
CFLAGS = -Dmalloc=cpputest_malloc -Dfree=cpputest_free
CPPFLAGS =
GCOVFLAGS = -fprofile-arcs -ftest-coverage
LDFLAGS = -lpthread
#USER_LIBS = -lpthread
# This line is overriding the default new macros. This is helpful
# when using std library includes like <list> and other containers
# so that memory leak detection does not conflict with stl.
CPPUTEST_MEMLEAK_DETECTOR_NEW_MACRO_FILE = -include ApplicationLib/ExamplesNewOverrides.h
SRC_DIRS = \
ApplicationLib
TEST_SRC_DIRS = \
AllTests
INCLUDE_DIRS =\
.\
ApplicationLib\
$(CPPUTEST_HOME)/include\
include $(CPPUTEST_HOME)/build/MakefileWorker.mk
As you can see the pthread lib is given to the linker with the LDFLAGS....
somebody similar experience? or maybe knows where the problem is?
Will be thankful for any tips!
thx to #Keith Marshall and #MadScientist,
so instead of
LDFLAGS = -lpthread
I used:
LD_LIBRARIES += -lpthread
and placed this line directly before:
include $(CPPUTEST_HOME)/build/MakefileWorker.mk
Now it works.
As can be seen in the Catalogue of Built-In Rules:
Linking a single object file
n is made automatically from n.o by running the linker (usually called
ld) via the C compiler. The precise recipe used is:
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
and Variables Used by Implicit Rules:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker,
ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable
instead.
So in this case -lpthread should be set or added to LDLIBS, not LDFLAGS.
Related
I'm compiling a Fortran code to obtain shared library .so. In the code it uses a module. The compiling has no problem while it reports undefined symbol error when opening the .so library.
Code mesh_map.F are as follows:
#include "cfx5ext.h"
dllexport(mesh_map)
SUBROUTINE mesh_map (CZ, DZ, IZ, LZ, RZ)
USE EXTRA_FLUID2
USE ISO_C_BINDING
USE IFPORT
IMPLICIT NONE
CHARACTER*(1) CZ(*)
DOUBLE PRECISION DZ(*)
INTEGER IZ(*)
LOGICAL LZ(*)
REAL RZ(*)
MAP_STATUS = 1
END
extra_fluid2.f90:
Module EXTRA_FLUID2
INTEGER :: map_status = 0
end module EXTRA_FLUID2
Compiling command:
ifort -c extra_fluid2.f90
/home/xxx/intel/oneapi/compiler/2021.4.0/linux/bin/intel64/ifort -fpic -assume 2underscore -check uninit -warn declarations -diag-error 6717 -ftz -O2 -fp-speculation=safe -fp-model=precise -fp-model=source -fimf-arch-consistency=true -qno-opt-dynamic-align -fpe0 -fomit-frame-pointer -real-size 32 -integer-size 32 -I/usr/ansys_inc/v192/CFX/include -o linux-amd64/ifort/mesh_map.o -c mesh_map.F
-lrt/xxx/intel/oneapi/compiler/2021.4.0/linux/bin/intel64/ifort -shared -o ./linux-amd64/ifort/libmesh_map.so linux-amd64/ifort/mesh_map.o extra_fluid2.o
When I check the .so library using:
ldd -r libmesh_map.so
The result shows as:
undefined symbol: extra_fluid2_mp_map_status__ (./libmesh_map.so)
How can I fix this? Thanks.
You must use -assume 2underscore in both compilations, using/not using the option cannot be mixed.
Also extra_fluid2.f90 should be compiled with option -fpic. It's generally a bad idea to use different sets of flags for files that are supposed to go into the same executable or shared object.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 4 years ago.
I am trying to compile a Fortran 90 code that uses HDF5. For that purpose, I am using the following Makefile:
# Location of HDF5 binaries (with include/ and lib/ underneath)
HDF5 = /fs/posgrado16/other0/guido/libraries/hdf5/serial
# Compiler
FC = gfortran
# ------ No machine-specific paths/variables after this -----
FORTRANLIB=-I$(HDF5)/include $(HDF5)/lib/libhdf5_fortran.a
FSOURCE = h5_crtgrpar.f90
OBJECTS = $(FSOURCE:.f90=.o)
EXECUTABLE = $(FSOURCE:.f90=.exe)
LIBSHDF = $(FORTRANLIB) $(HDF5)/lib/libhdf5.a
all:$(EXECUTABLE)
$(EXECUTABLE):$(OBJECTS)
$(FC) -o $# $^ $(LIBSHDF)
$(OBJECTS):$(FSOURCE)
$(FC) -c $# $< $(LIBSHDF)
.PHONY : clean
clean:
rm -f $(FSOURCE) $(OBJECTS) *.h5
But, I get the following error:
$ make -f Makefilef
gfortran -o h5_crtgrpar.exe h5_crtgrpar.o -I/fs/posgrado16/other0/guido /libraries/hdf5/serial/include /fs/posgrado16/other0/guido/libraries/hdf5/serial/lib/libhdf5_fortran.a /fs/posgrado16/other0/guido/libraries /hdf5/serial/lib/libhdf5.a
/fs/posgrado16/other0/guido/libraries/hdf5/serial/lib/libhdf5.a(H5PL.o): In function `H5PL_term_interface':
H5PL.c:(.text+0x205): undefined reference to `dlclose'
/fs/posgrado16/other0/guido/libraries/hdf5/serial/lib/libhdf5.a(H5PL.o): In function `H5PL_load':
H5PL.c:(.text+0x477): undefined reference to `dlsym'
H5PL.c:(.text+0x5be): undefined reference to `dlopen'
H5PL.c:(.text+0x5d7): undefined reference to `dlsym'
H5PL.c:(.text+0x704): undefined reference to `dlclose'
H5PL.c:(.text+0x789): undefined reference to `dlerror'
H5PL.c:(.text+0x960): undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
make: *** [h5_crtgrpar.exe] Error 1
I have no idea what the error is. Probably, there is something wrong with my Makefile.
To compile Fortran code with HDF5 enabled, you can replace
FC = gfortran
by
FC = h5fc
and skip all the hdf5 flags, as the h5fc wrapper will take care of those.
If you have some specific reason of calling the compiler by its name, you can learn about what flags are needed by calling
h5fc -show
that will show you what flags are added to the compiler.
On my computer (linux with gfortran), the result is:
gfortran -g -O2 -fstack-protector-strong -I/usr/include/hdf5/serial -L/usr/lib/x86_64-linux-gnu/hdf5/serial /usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5hl_fortran.a /usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5_hl.a /usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5_fortran.a /usr/lib/x86_64-linux-gnu/hdf5/serial/libhdf5.a -Wl,-z,relro -lpthread -lz -ldl -lm -Wl,-rpath -Wl,/usr/lib/x86_64-linux-gnu/hdf5/serial
Often you can get by with less flags than that, which you can find with some experimentation.
Given the error message you report, you lack the -ldl flags that enables linking of the dynamic linking library, see for isntance this other SO question.
I try to write a Makefile that takes several static libraries that have been created before and link the to an executable. Although one libary has a main-routine.
I get the error:
/lib/../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [dockSIM_gcc_release] Error 1
I tried it with just linking the library that has the main routine but the error stays the same and comes directly after invoking make.
The Makefile:
SHELL = /bin/sh
RM=/bin/rm -f
CXX=g++
PROGNAME=dockSIM_gcc_release
DEFINES=-DDOCKSIM_VERBOSE=FALSE -DNDEBUG -DPRINT_LOG_MSG=0 -DPRINT_DEBUG_MSG=0
LDFLAGS = -fopenmp -g -O3 -std=c++11 -mavx -mstackrealign -fstrict-aliasing
LIBS= -lnagc_mkl -lm -L../externalCode -lpardiso500-GNU481-X86-64 -lacml
FILENAMES = commandInterpreter_lib.a
OBJNAMES =
all: $(PROGNAME)
$(PROGNAME): $(FILENAMES)
$(CXX) $(LDFLAGS) $(DEFINES) -o $(PROGNAME) $(FILENAMES)
clean:
$(RM) *.mo *.ho *.o $(PROGNAME) core *~
test:
echo $(FILENAMES)
showlibs:
echo $(LIBS)
The flags are compatible with those that were used to compile the code.
g++ 4.9.3 is used.
Signature of the main-Routine:
int main(int argc, char* argv[])
Thanks for help and kind regards.
I can only guess what's wrong.
There is more to linking a static library than just a convenient bundle of object files to reduce command line length. In addition to that, the linker only links in object files which it thinks are needed. An object file is needed if there's some undefined symbol that the linker is looking for, that is contained in that object. If there's no symbol that the linker needs in the object, then the linker ignores the object and doesn't link it.
The normal way to build a program is to have the main program listed as object files on the command line: the linker always links every object file. This gives the linker a set of symbols which are defined (by the object files) and undefined (things the object files use but that aren't defined by them). Then the linker will go through the libraries on the link line and add in object files that resolve undefined symbols. These object files in turn may have other undefined symbols that the linker will need to resolve later, etc.
All I can guess is that by not having any object files on your link line, the linker doesn't see the object file in the library containing main as needed and so it doesn't link it.
I don't know why building with debug vs. non-debug makes a difference.
I didn't understand your comment about why you need to do things this way: even if the person who knew about this left, someone will need to learn about it to maintain the software.
In any event you have a few options.
One simple one is to use the "ar" program to extract out the object file containing main and link it directly: in addition to adding objects to libraries ar can extract them. Then you can link that object directly. See the man page for ar.
Another would be to look at the documentation for your compiler and linker and find flags that will force it to include the entire library, not just the unresolved symbols in the library. For the GCC/binutils linker, for example, you can pass -Wl,--whole-archive before the libraries you want to be fully included on the command line, then -Wl,--no-whole-archive after them to turn off that feature.
Hadoop n00b here, just started playing around with Hadoop Pipes. I'm getting linker errors while compiling a simple WordCount example using hadoop-0.20.203 (current most recent version) that did not appear for the same code in hadoop-0.20.2
Linker errors of the form: undefined reference to `EVP_sha1' in HadoopPipes.cc.
EVP_sha1 (and all of the undefined references I get) are part of the openssl library which HadoopPipes.cc from hadoop-0.20.203 uses, but hadoop-0.20.2 does not.
I've tried adjusting my makefile to link to the ssl libraries, but I'm still out of luck. Any ideas would be greatly appreciated. Thanks!
PS, here is my current makefile:
CC = g++
HADOOP_INSTALL = /usr/local/hadoop-0.20.203.0
SSL_INSTALL = /usr/local/ssl
PLATFORM = Linux-amd64-64
CPPFLAGS = -m64 -I$(HADOOP_INSTALL)/c++/$(PLATFORM)/include -I$(SSL_INSTALL)/include
WordCount: WordCount.cc
$(CC) $(CPPFLAGS) $< -Wall -Wextra -L$(SSL_INSTALL)/lib -lssl -lcrypto -L$(HADOOP_INSTALL)/c++/$(PLATFORM)/lib -lhadooppipes -lhadooputils -lpthread -g -O2 -o $#
The actual program I'm using can be found at http://cs.smith.edu/dftwiki/index.php/Hadoop_Tutorial_2.2_--_Running_C%2B%2B_Programs_on_Hadoop
Had same problem here: answer is to add -lcrypto to the compile command line:
http://grokbase.com/p/hadoop.apache.org/common-user/2011/06/re-linker-errors-with-hadoop-pipes/09zqdt5grdudu7no7q6k3gfcynpy
Here is a patch to fix the build process:
diff --git src/examples/pipes/Makefile.in src/examples/pipes/Makefile.in
index 17efa2a..1d8af8e 100644
--- src/examples/pipes/Makefile.in
+++ src/examples/pipes/Makefile.in
## -233,7 +233,7 ## AM_CXXFLAGS = -Wall -I$(HADOOP_UTILS_PREFIX)/include \
-I$(HADOOP_PIPES_PREFIX)/include
LDADD = -L$(HADOOP_UTILS_PREFIX)/lib -L$(HADOOP_PIPES_PREFIX)/lib \
- -lhadooppipes -lhadooputils
+ -lhadooppipes -lhadooputils -lcrypto
# Define the sources for each program
You just need to make some changes to your Makefile. The libraries that natively accompany hadoop seem not to do it. You'll need to "re-make" them and change your linked path.
A comprehensive answer to this can be found at http://goo.gl/y5iGZF.
I'm trying to use the sprintf() function. Therefore I have to include the stdio.h in my C project. If I compile the project without including the stdio.h in my makefile, the compiler generates the error that sprintf() is a unknown function. Including the stdio.h to the makefile generates the error that there is "no rule to make target."
The makefile template gives the options as follows:
NAME = test
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld -v
AR = arm-none-eabi-ar
AS = arm-none-eabi-as
CP = arm-none-eabi-objcopy
OD = arm-none-eabi-objdump
CFLAGS = -I./ -c -fno-common -O0 -g -mcpu=cortex-m3 -mthumb
AFLAGS = -ahls -mapcs-32 -o crt.o
ASFLAGS = -Wa,-gstabs
LFLAGS = -Tlinkerscript_rom.cmd -nostartfiles
CPFLAGS = -Obinary
ODFLAGS = -S
I hope that you can help me out, because I have no desire to rewrite every standard function.
Sven
Makefiles don't read include files. The C preprocessor reads include files, before the resulting file is compiled by the compiler. You should include the header in your C file. Just add:
#include <stdio.h>
Somewhere close to the top, before any function definitions etc.
This will show a declaration of the function to the compiler, which will remove the warning.
Just include stdio.h at the top of your c file
#include <stdio.h>
The only reason to put a .h file in your makefile is so that the files dependent upon your header will be recompiled if anything in the header is changed. Needless to say, this is most commonly with header files you have written.
If there is an error after including stdio.h, you have a broken tool chain. If you update your question to indicate your platform, we may be able to help you fix it :)