0

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!

JohnDoe
  • 825
  • 1
  • 13
  • 31
  • 1
    The first thing you should do is unset the "quiet" mode so that the command lines that make invokes are being printed. Then examine the command line used for linking and make sure that the flags you expect to see are actually there. You show `LDFLAGS` being set but since you don't show the linking rule there's no way to know if that variable is really used during linking. Also, on UNIX systems anyway, you need to use the `-pthread` flag during both compilation and linking. – MadScientist Aug 04 '15 at 12:16
  • In addition to the comment by @MadScientist, you should also note that, if `LDFLAGS` is interpreted as it is used in GNU make's default rules, it is evaluated far too early to pass _any_ library effectively to the linker. You should _not_ specify `-lpthread` in `LDFLAGS`; on the linker command line `-lpthread` must come _after_ all object files which require it, but `LDFLAGS` may be interpreted _before_ them. Conventionally, you may add libraries to `LIBS`, _not_ to `LDFLAGS`, and you should then ensure that `$(LIBS)` appears _after_ all object files on the linker command line. – Keith Marshall Aug 04 '15 at 15:10
  • Good point regarding `LDFLAGS`. However, you want to use `LDLIBS` not `LIBS`... `LIBS` is not a standard variable in GNU make. – MadScientist Aug 04 '15 at 18:32
  • @MadScientist: Yes, I can see the use of `$(LDLIBS)` in the output of `make -p | grep LINK`. However, neither `LIBS` nor `LDLIBS` is mandated by the GNU Coding Standards, but `LIBS` is conventional for autotooled projects, and documented as such in the GNU autoconf manual. – Keith Marshall Aug 04 '15 at 19:26

2 Answers2

0

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.

JohnDoe
  • 825
  • 1
  • 13
  • 31
  • 1
    So, `LD_LIBRARIES` is presumably used, in your `MakefileWorker.mk` extension makefile, (which you _should_ have shown us -- at least to the extent of its pertinent part -- BTW), in the fashion of `LIBS` in a GNU autotooled project, or of `LDLIBS` in GNU make's built-in default rules. Perhaps you should also have heeded @MadScientist's advice to use the `-pthread` option, (e.g. in `CFLAGS`); had you done so, and if your makefile uses the compiler driver, as it should, to invoke the linker, then `-lpthread` would have been added implicitly, in its correct linking order position. – Keith Marshall Aug 05 '15 at 10:52
0

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.