【问题标题】:CppuTest: undefined reference to pthread during final linkingCppuTest:最终链接期间对 pthread 的未定义引用
【发布时间】:2015-10-26 13:56:42
【问题描述】:

我是 cppuTest 的新手,实际上我正在尝试在 CppuTest 根目录中构建 ./examples。源文件和测试文件编译没有问题,但我停留在最后的链接阶段,我得到这个错误:

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

我在 Windows 7 上使用 MinGW。MinGW 还包含 pthread.a 库。我的 makefil 如下所示:

#---------
#
# 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

如您所见,pthread 库是通过 LDFLAGS.... 提供给链接器的。

有人有类似经历吗?或者也许知道问题出在哪里? 将感谢任何提示!

【问题讨论】:

  • 您应该做的第一件事是取消设置“安静”模式,以便打印调用的命令行。然后检查用于链接的命令行并确保您希望看到的标志确实存在。您显示 LDFLAGS 正在设置,但由于您没有显示链接规则,因此无法知道该变量是否在链接期间真正使用。此外,无论如何,在 UNIX 系统上,您需要在编译和链接期间使用 -pthread 标志。
  • 除了@MadScientist 的评论之外,您还应该注意,如果LDFLAGS 被解释为在 GNU make 的默认规则中使用,那么它的评估太早而无法通过 任何 库有效地连接到链接器。您应该LDFLAGS 中指定-lpthread;在链接器命令行上,-lpthread 必须出现在 所有需要它的目标文件之后,但 LDFLAGS 可以在 之前 被解释。按照惯例,您可以将库添加到LIBSnotLDFLAGS,然后您应该确保$(LIBS) 出现在链接器命令行上的所有目标文件之后 .
  • 关于LDFLAGS 的要点。但是,您想使用LDLIBS 而不是LIBS...LIBS 不是 GNU make 中的标准变量。
  • @MadScientist:是的,我可以在make -p | grep LINK 的输出中看到$(LDLIBS) 的使用。然而,LIBSLDLIBS 都不是 GNU 编码标准强制要求的,但 LIBS 是自动工具项目的惯例,并在 GNU autoconf 手册中记录。

标签: makefile mingw undefined-reference cpputest pthreads-win32


【解决方案1】:

感谢@Keith Marshall 和@MadScientist,

所以而不是 LDFLAGS = -lpthread

我用过:

LD_LIBRARIES += -lpthread

并将这一行直接放在前面:

include $(CPPUTEST_HOME)/build/MakefileWorker.mk

现在可以了。

【讨论】:

  • 所以,LD_LIBRARIES 可能在您的 MakefileWorker.mk 扩展生成文件中使用(您应该已经向我们展示了 - 至少在其相关部分的范围内-- 顺便说一句),在 GNU 自动工具项目中采用 LIBS 的方式,或者在 GNU make 的内置默认规则中采用 LDLIBS 的方式。也许你也应该听从@MadScientist 的建议,使用-pthread 选项,(例如在CFLAGS 中);如果你这样做了,并且如果你的 makefile 使用编译器驱动程序来调用链接器,那么 -lpthread 将被隐式添加到正确的链接顺序位置。
【解决方案2】:

Catalogue of Built-In Rules中可以看到:

链接单个对象文件

n 通过运行链接器(通常称为 ld) 通过 C 编译器。使用的精确配方是:

$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)

Variables Used by Implicit Rules:

LDFLAGS

在应该调用链接器时提供给编译器的额外标志, ld,如-L。应将库 (-lfoo) 添加到 LDLIBS 变量中 而是。

所以在这种情况下,-lpthread 应该设置或添加到 LDLIBS,而不是 LDFLAGS。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    相关资源
    最近更新 更多