C 链接在我的Makefile中没有出现;返回';对“main'”的未定义引用;
这个简单的程序(两个.c文件和一个.h)从命令行正确编译和链接。但是,我的Makefile在链接阶段抛出了一个错误。选项卡的正确使用已生效C 链接在我的Makefile中没有出现;返回';对“main'”的未定义引用;,c,linux,gcc,makefile,C,Linux,Gcc,Makefile,这个简单的程序(两个.c文件和一个.h)从命令行正确编译和链接。但是,我的Makefile在链接阶段抛出了一个错误。选项卡的正确使用已生效 CC = gcc BINDIR = bin/ OBJDIR = obj/ SRCDIR = src/ MKDIR = mkdir -p RM = rm -rf SRC = $(wildcard $(SRCDIR)*.c) _OBJS = $(patsubst $(SRCDIR)%.c, %.o, $(SRC))
CC = gcc
BINDIR = bin/
OBJDIR = obj/
SRCDIR = src/
MKDIR = mkdir -p
RM = rm -rf
SRC = $(wildcard $(SRCDIR)*.c)
_OBJS = $(patsubst $(SRCDIR)%.c, %.o, $(SRC))
OBJS = $(addprefix $(OBJDIR), $(_OBJS))
CFLAGS = -Wall -g -Iinclude
.PHONY: all
all: $(BIN)
_BIN = a.out
BIN = $(addprefix $(BINDIR), $(_BIN))
$(BIN): $(OBJS) $(BINDIR)
$(CC) -o $@ $(CFLAGS) $<
$(BINDIR):
$(MKDIR) $(BINDIR)
$(OBJS): $(SRC) $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR):
$(MKDIR) $(OBJDIR)
.PHONY: clean
clean:
@echo "Cleaning things up..."
$(RM) $(OBJDIR) $(BINDIR)
.c文件位于src/目录中,.h文件位于include/目录中。Makefile编译代码,创建obj/目录,并将main.o和hellomake.o放在其中。然而,这就是问题的症结所在。以下是gcc的投诉:
$ make
mkdir -p obj/
gcc -Wall -g -Iinclude -c src/hellomake.c -o obj/hellomake.o gcc -Wall -g -Iinclude -c src/hellomake.c -o obj/main.o mkdir -p bin/ gcc -o bin/a.out -Wall -g -Iinclude
obj/hellomake.o /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status make: *** [Makefile:34: bin/a.out] Error 1
有许多问题 我将从(例如)BINDIR等的
/
中删除/
patsubst
不正确。它需要$(OBJDIR)
中的到
使用OBJS是不必要的/有害的
$(OBJS)
的规则不正确。它使用第一个prereq源创建了两个.o
文件,因此[function]main
被定义了两次。它需要一个模式规则
使用$(BINDIR)
作为$(BIN)
的预请求,在gcc
行的末尾添加了BIN/
[它抱怨]
正如M.Oehm
所述,$当您链接(target$(BIN)
)时,您需要$^
(所有先决条件)而不是$
#include <stdio.h>
#include "hellomake.h"
void myPrintHelloMake(void) {
puts("Hello makefiles!");
}
#ifndef __HELLO_H__
#define __HELLO_H__
void myPrintHelloMake(void);
#endif
$ make
mkdir -p obj/
gcc -Wall -g -Iinclude -c src/hellomake.c -o obj/hellomake.o gcc -Wall -g -Iinclude -c src/hellomake.c -o obj/main.o mkdir -p bin/ gcc -o bin/a.out -Wall -g -Iinclude
obj/hellomake.o /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status make: *** [Makefile:34: bin/a.out] Error 1
CC = gcc
BINDIR = bin
OBJDIR = obj
SRCDIR = src
MKDIR = mkdir -p
RM = rm -rf
SRC = $(wildcard $(SRCDIR)/*.c)
###_OBJS = $(patsubst $(SRCDIR)%.c, %.o, $(SRC))
###OBJS = $(addprefix $(OBJDIR), $(_OBJS))
OBJS = $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SRC))
CFLAGS = -Wall -g -Iinclude
_BIN = a.out
BIN = $(addprefix $(BINDIR)/, $(_BIN))
.PHONY: all
all: $(BINDIR) $(OBJDIR) $(BIN)
####$(BIN): $(OBJS) $(BINDIR)
$(BIN): $(OBJS) $(BINDIR)
###$(CC) -o $@ $(CFLAGS) $<
$(CC) -o $@ $(CFLAGS) $(OBJS)
$(BINDIR):
$(MKDIR) $(BINDIR)
###$(OBJS): $(SRC) $(OBJDIR)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR):
$(MKDIR) $(OBJDIR)
.PHONY: clean
clean:
@echo "Cleaning things up..."
$(RM) $(OBJDIR) $(BINDIR)