【问题标题】:Makefile - undefined reference to functionMakefile - 未定义的函数引用
【发布时间】:2015-10-27 20:32:03
【问题描述】:

我有一个示例项目,我正在使用一本书“Learn C the hard way”。但我不能让它编译。

我认为我的 Makefile 有问题。我想做的是构建一个库,然后从中调用一些函数。但是在编译测试时我得到了

cthehardway/dlib/tests/list_tests.c:36: undefined reference to `List_pop'

这是我的 Makefile:

CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local

SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))

TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))

TARGET=build/libd.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))

# The Target Build
all: $(TARGET) $(SO_TARGET) tests

dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all

$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
    ar rcs $@ $(OBJECTS)
    ranlib $@

$(SO_TARGET): $(TARGET) $(OBJECTS)
    $(CC) -shared -o $@ $(OBJECTS)

build:
    @mkdir -p build
    @mkdir -p bin

# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
    sh ./tests/runtests.sh

# The Cleaner
clean:
    rm -rf build $(OBJECTS) $(TESTS)
    rm -f tests/tests.log 
    find . -name "*.gc*" -exec rm {} \;
    rm -rf `find . -name "*.dSYM" -print`

# The Install
install: all
    install -d $(DESTDIR)/$(PREFIX)/lib/
    install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/

# The Checker
check:
    @echo Files with potentially dangerous functions.
    @egrep '[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)\
        |stpn?cpy|a?sn?printf|byte_)' $(SOURCES) || true

这里是项目本身的链接(它很小,只有几个文件); 项目为dlib文件夹,外部文件无视。

只有测试目标失败。该库构建良好。

https://github.com/Voley/cthehardway

【问题讨论】:

  • 在错误发生之前 make 的输出是什么?
  • 在你知道如何没有 Make之前,你不能用Make做任何事情。您应该尝试“手动”构建测试代码(即从命令行,不使用 Make)。如果它有效,这是一个 Make 问题,如果它没有,那么它不是。无论哪种方式,您都可以想出一个更简单的示例。
  • @Beta 仍然没有“手动”构建,给出同样的错误

标签: c gcc makefile c99


【解决方案1】:

您没有在测试链接中包含您的库。

$(SO_TARGET): $(TARGET) $(OBJECTS)
    $(CC) -shared -o $@ $(OBJECTS)

您应该在最后一行包含$(TARGET)

至少,我认为是这样的。这是一个依赖项,所以我假设你想链接它。

【讨论】:

  • 不幸的是,这没有帮助。我相信这是链接器问题,因为即使我手动输入所有内容,它仍然会失败。
  • @Dvole 确保它在 $(OBJECTS) 的左侧
  • 哦。哇。呃,请确保您在调用 RUN_TESTS 宏之前包含定义这些头文件的头文件。您看到的是编译错误,而不是生成文件问题或链接问题。
  • 我包括它。这是项目 - github.com/Voley/c_troubles 如您所见,我 #include minunit.h 在文件 github.com/Voley/c_troubles/blob/master/tests/list_tests.c 的顶部
  • 嗯,您实际上没有进行测试的规则。我不确定这是如何工作的。此外,当您查看正在构建测试的命令行时,我不确定包含库的选项如何与 gcc 交互,一步一步制作精灵。通常,当您调用 $(LD) 时,库需要位于需要它们的 .o 之后。然后你打电话给 $(CC) 做整个事情....我不知道。尝试将 -u List_push 添加到您的 OPTFLAGS 中,看看您的一些错误是否消失。如果是这样,那就是链接顺序问题。
猜你喜欢
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
  • 2018-05-25
相关资源
最近更新 更多