make:为test目录中的每个文件创建一个测试二进制文件

时间:2016-07-26 17:55:17

标签: c makefile gnu-make

对于我正在构建的小型库,我有一个简单的结构如下所示。

  • 我希望make buildlibproj.a
  • 下的来源构建库(./source
  • 我希望make build_test./test前缀为test_的每个源文件构建到自己的二进制文件中

我可以很好地构建库libproj.a,但无法弄清楚如何构建测试。我在尝试构建/cygdrive/d/Source/proj/build/obj/test_proj.o:test_proj.c:(.text+0x15): undefined reference to 'test'时遇到以下链接器错误。

目录结构

+---build
|   +---lib
|   +---obj
|   \---test
+---include
|   \---proj
+---source
\---test

生成文件

PROJECT             = proj
LIBNAME             = lib$(PROJECT).a

CFLAGS              = -Wall -Wextra -O0

DIR_ROOT            = $(abspath .)
DIR_SRC_LIB         = $(DIR_ROOT)/source
DIR_SRC_TEST        = $(DIR_ROOT)/test

DIR_BLD_OBJ         = $(DIR_ROOT)/build/obj
DIR_BLD_LIB         = $(DIR_ROOT)/build/lib
DIR_BLD_TEST        = $(DIR_ROOT)/build/test

LST_OBJ_LIB         = $(patsubst $(DIR_SRC_LIB)/%.c, $(DIR_BLD_OBJ)/%.o, $(wildcard $(DIR_SRC_LIB)/*.c))
LST_OBJ_TEST        = $(patsubst $(DIR_SRC_TEST)/%.c, $(DIR_BLD_OBJ)/%.o, $(wildcard $(DIR_SRC_TEST)/*.c))
LST_BIN_TEST        = $(patsubst $(DIR_SRC_TEST)/%.c, $(DIR_BLD_TEST)/%, $(wildcard $(DIR_SRC_TEST)/test_*.c))

INCLUDES            = -I $(DIR_ROOT)/include

clean:
    $(RM) $(LST_OBJ_LIB)
    $(RM) $(LST_OBJ_TEST)

build:
    $(info build)

build-test: $(LST_BIN_TEST)
    $(info build-test)

run-test:
    $(info run-test)

install:
    $(info install)

$(LIBNAME): $(LST_OBJ_LIB)
    $(AR) rvs $(DIR_BLD_LIB)/$@ $^

$(DIR_BLD_OBJ)/%.o: $(DIR_SRC_LIB)/%.c
    $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(DIR_BLD_TEST)/%: $(DIR_BLD_OBJ)/%.o $(LIBNAME)
    $(CC) $(LDFLAGS) -L $(DIR_BLD_LIB) -l $(PROJECT) $< -o $@

$(DIR_BLD_OBJ)/%.o: $(DIR_SRC_TEST)/%.c
    $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

1 个答案:

答案 0 :(得分:0)

我的猜测是这一行:

$(CC) $(LDFLAGS) -L $(DIR_BLD_LIB) -l $(PROJECT) $< -o $@

错了。您在目标文件之前传递给编译器(我假设gcc)库。如果您的编译器充当gcc,那么库中的代码将被丢弃,因为它在解析它们时尚未被引用see -l option documentation

应该是

$(CC) $(LDFLAGS) -L $(DIR_BLD_LIB) $< -l $(PROJECT) -o $@

(请注意$<

的更改位置

此外,请记住图书馆的顺序非常重要:请参阅此优秀的explanation