C語言有庫和主測驗驅動,雖然庫可以編譯成功,但是主測驗驅動不行。
以下是目錄結構:
qxu@xqiang-mac-1:~/test/test_makefile$ ll
total 0
drwxr-xr-x 3 qxu staff 96 Nov 23 13:19 include
drwxr-xr-x 6 qxu staff 192 Nov 23 13:31 print_ascii_tree
drwxr-xr-x 5 qxu staff 160 Nov 23 13:33 test_main_driver
qxu@xqiang-mac-1:~/test/test_makefile$ ll include/
total 8
-rw-r--r-- 1 qxu staff 706 Nov 23 12:12 print_ascii_tree.h
qxu@xqiang-mac-1:~/test/test_makefile$ ll print_ascii_tree/
total 32
-rw-r--r-- 1 qxu staff 250 Nov 23 13:31 Makefile
-rw-r--r-- 1 qxu staff 9122 Nov 23 12:12 print_ascii_tree.c
qxu@xqiang-mac-1:~/test/test_makefile$ ll test_main_driver/
total 16
-rw-r--r--@ 1 qxu staff 616 Nov 23 13:33 Makefile
-rw-r--r--@ 1 qxu staff 918 Nov 23 11:51 main.c
這是庫的生成檔案:
qxu@xqiang-mac-1:~/test/test_makefile/print_ascii_tree$ cat Makefile
AR = ar -rcs
RM = rm -rf
CC = gcc
CFLAGS = -I../include
libprint_ascii_tree.a: print_ascii_tree.o
$(AR) libprint_ascii_tree.a print_ascii_tree.o
print_ascii_tree.o: print_ascii_tree.c
$(CC) $(CFLAGS) -c print_ascii_tree.c
clean:
$(RM) *.o *.a
這個庫可以順利編譯:
qxu@xqiang-mac-1:~/test/test_makefile/print_ascii_tree$ make
gcc -I../include -c print_ascii_tree.c
ar -rcs libprint_ascii_tree.a print_ascii_tree.o
qxu@xqiang-mac-1:~/test/test_makefile/print_ascii_tree$ ll
total 64
-rw-r--r-- 1 qxu staff 250 Nov 23 13:31 Makefile
-rw-r--r-- 1 qxu staff 7672 Nov 23 13:38 libprint_ascii_tree.a
-rw-r--r-- 1 qxu staff 9122 Nov 23 12:12 print_ascii_tree.c
-rw-r--r-- 1 qxu staff 7128 Nov 23 13:38 print_ascii_tree.o
這是測驗驅動程式的 Makefile:
qxu@xqiang-mac-1:~/test/test_makefile/test_main_driver$ cat Makefile
program_NAME := main.out
SRCS = main.c
OBJS := ${SRCS:.c=.o}
CC = gcc
CFLAGS = -fsanitize=address -Wall -Wextra -g
program_INCLUDE_DIRS := ../include
program_LIBRARY_DIRS := ../print_ascii_tree
program_LIBRARIES := print_ascii_tree
CFLAGS = $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir))
LDFLAGS = $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir))
LDFLAGS = $(foreach library,$(program_LIBRARIES),-l$(library))
LINK.c := $(CC) $(CFLAGS) $(LDFLAGS)
.PHONY: all
all: $(program_NAME)
$(program_NAME): $(OBJS)
$(LINK.c) $(program_OBJS) -o $(program_NAME)
clean:
rm -rf *.o *.out
這是錯誤:
qxu@xqiang-mac-1:~/test/test_makefile/test_main_driver$ make
gcc -fsanitize=address -Wall -Wextra -g -I../include -c -o main.o main.c
gcc -fsanitize=address -Wall -Wextra -g -I../include -L../print_ascii_tree -lprint_ascii_tree -o main.out
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main.out] Error 1
qxu@xqiang-mac-1:~/test/test_makefile/test_main_driver$ ll
total 32
-rw-r--r--@ 1 qxu staff 617 Nov 23 13:39 Makefile
-rw-r--r--@ 1 qxu staff 908 Nov 23 13:40 main.c
-rw-r--r-- 1 qxu staff 6496 Nov 23 13:40 main.o
看起來已main.o編譯,但無法與庫鏈接到主可執行檔案中?
不確定 Makefile 中有什么問題。
PS這是什么main.c:
qxu@xqiang-mac-1:~/test/test_makefile/test_main_driver$ cat main.c
#include "print_ascii_tree.h"
int main()
{
printf("asdf\n");
// A sample use of these functions. Start with the empty tree
// insert some stuff into it, and then delete it
NodePtr root;
root = NULL;
make_empty(root);
printf("\nAfter inserting key 10..\n");
root = insert(10, root);
print_ascii_tree(root);
printf("\nAfter inserting key 5..\n");
root = insert(5, root);
print_ascii_tree(root);
printf("\nAfter inserting key 15..\n");
root = insert(15, root);
print_ascii_tree(root);
printf("\nAfter inserting keys 9, 13..\n");
root = insert(9, root);
root = insert(13, root);
print_ascii_tree(root);
printf("\nAfter inserting keys 2, 6, 12, 14, ..\n");
root = insert(2, root);
root = insert(6, root);
root = insert(12, root);
root = insert(14, root);
print_ascii_tree(root);
make_empty(root);
}
uj5u.com熱心網友回復:
這里:
$(program_NAME): $(OBJS)
$(LINK.c) $(program_OBJS) -o $(program_NAME)
您使用program_OBJS未定義的變數。如果您將其修復為$(OBJS)或$^,則還有另一個問題LINK.c。它被定義為:
LINK.c := $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
這意味著生成的命令將首先和main.o第二個庫:
-lprint_ascii_tree main.o
并且聯結器不會找到 中使用的符號main.o,這些符號是在庫中定義的。
我不確定您是否可以使用單獨的LINK.c變數使其作業,但這應該有效:
$(program_NAME): $(OBJS)
$(CC) $(CFLAGS) $(CPPFLAGS) $^ $(LDFLAGS) -o $@
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/364733.html
上一篇:C中不止一個重復的元素
下一篇:檢查C中條件的順序
