【问题标题】:How to fix error in function `_start': (.text+0x20): undefined reference to `main'如何修复函数“_start”中的错误:(.text+0x20): undefined reference to `main'
【发布时间】:2019-03-28 18:59:13
【问题描述】:

我正在使用 Vagrant 和 Virtualbox 运行 Ubuntu 18.0.4 虚拟机。我正在编写一个 C 程序来管理所述机器上的虚拟内存,它由许多 C 和头文件组成。每次我在虚拟机中运行 make 时,都会收到此错误:

make[1]: Entering directory '/vagrant'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In 
function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:45: recipe for target 'vm-sim' failed
make[1]: *** [vm-sim] Error 1
make[1]: Leaving directory '/vagrant'
Makefile:23: recipe for target 'all' failed
make: *** [all] Error 2

这是我的 Makefile:

TARGET = vm-sim
CC     = gcc
CFLAGS = -Wall -Wextra -Wsign-conversion -Wpointer-arith -Wcast-qual - 
Wwrite-strings -Wshadow -Wmissing-prototypes -Wpedantic -Wwrite-strings -g - 
std=gnu99 -lm

LFLAGS =

SRCDIR = *-src
INCDIR = $(SRCDIR)
BINDIR = .

SUBMIT_FILES  = $(SRC) $(INC) Makefile
SUBMISSION_NAME = project3-vm

SRC := $(wildcard $(SRCDIR)/*.c)
INC := $(wildcard $(INCDIR)/*.h)

INCFLAGS := $(patsubst %/,-I%,$(dir $(wildcard $(INCDIR)/.)))

.PHONY: all
all:
@$(MAKE) release && \
echo "$$(tput setaf 3)$$(tput bold)Note:$$(tput sgr0) this project compiled 
with release flags by default. To compile for debugging, please use $$(tput 
setaf 6)$$(tput bold)make debug$$(tput sgr0)."

.PHONY: debug
debug: CFLAGS += -ggdb -g3 -DDEBUG
debug: $(BINDIR)/$(TARGET)

.PHONY: release
release: CFLAGS += -mtune=native -O2
release: $(BINDIR)/$(TARGET)

.PHONY: clean
clean:
@rm -f $(BINDIR)/$(TARGET)
@rm -rf $(BINDIR)/$(TARGET).dSYM

.PHONY: submit
submit:
@(tar zcfh $(SUBMISSION_NAME).tar.gz $(SUBMIT_FILES) && \
echo "Created submission archive $$(tput 
bold)$(SUBMISSION_NAME).tar.gz$$(tput sgr0).")

$(BINDIR)/$(TARGET): $(SRC) $(INC)
@mkdir -p $(BINDIR)
@$(CC) $(CFLAGS) $(INCFLAGS) $(SRC) -o $@ $(LFLAGS)

我只定义了一个 main() 函数,但之前在另一个文件中定义了一个不同的函数;我认为这可能是问题所在,但不知道如何解决。

【问题讨论】:

  • 您是否使用包含main 函数的源文件进行构建?如果您从头开始重建,您是否看到该源文件被构建到目标文件中?该目标文件是否与可执行程序的其余文件链接?您需要检查 make 之后的 full 输出,例如make clean.
  • 这显然不是 main() 的多个定义的问题,而是main()no 定义的问题。完整的 rebuild all (make clean/make) 日志将向您显示正在编译和链接的内容 - 无论 main 定义在哪里 - 不在其中。
  • @Someprogrammerdude 恐怕我不确定你的意思。如何为 make 指定源文件?或者你的意思是我应该运行类似gcc filename.c -o filename 的东西?
  • 运行make clean。然后运行make release(或make debug)。 make 程序将向您显示为构建程序而运行的确切命令。包含您的 main 函数的源文件是否列为正在构建?您确实有一个包含main 函数的源文件吗?

标签: c vagrant virtualbox linker-errors


【解决方案1】:

以下生成文件:

  1. 不适用于您的特定目录布局
  2. 展示了一种编写 makefile 的好方法(但不是很好)
  3. 展示了一种创建依赖文件的方法(不过,gcc 可以直接用于生成这些文件
  4. 为 Linux 操作系统编写
  5. 这是一个通用的make文件,调用make时需要参数:-D name=executablename

现在,生成文件:

SHELL = /bin/sh


BINDIR  :=  /home/user/bin


.PHONY: all
all : $(BINDIR)/$(name) 



SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
DEP := $(SRC:.c=.d)
INC := $(SRC:.c=.h)




MAKE    :=  /usr/bin/make

CC      :=  /usr/bin/gcc

CP      :=  cp

MV      := mv

LDFLAGS :=  -L/usr/local/lib

DEBUG   :=  -ggdb3

CCFLAGS :=  $(DEBUG) -Wall -Wextra -pedantic -Wconversion -std=gnu11


LIBS    :=   -lssl -ldl -lrt -lz -lc -lm



#
# link the .o files into the executable 
# using the linker flags
# -- explicit rule
#
$(name): $(OBJ)  
    #
    # ======= $(name) Link Start =========
    $(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
    # ======= $(name) Link Done ==========
    #



# note:
# using MV rather than CP results in all executables being re-made everytime
$(BINDIR)/$(name): $(name)
    #
    # ======= $(name) Copy Start =========
    sudo $(CP) $(name) $(BINDIR)/.
    # ======= $(name) Copy Done ==========
    #



#
#create dependancy files -- inference rule
# list makefile.mak as dependancy so changing makfile forces rebuild
#
%.d: %.c 
    # 
    # ========= START $< TO $@ =========
    $(CC)  $< > $@.$$$$;                      \
    sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;     \
    rm -f $@.$$$$
    # ========= END $< TO $@ =========



# 
# compile the .c file into .o files using the compiler flags
# -- inference rule
#
%.o: %.c %.d 
    # 
    # ========= START $< TO $@ =========
    $(CC) $(CCFLAGS) -c $< -o $@ -I. 
    # ========= END $< TO $@ =========
    # 



.PHONY: clean
clean: 
    # ========== CLEANING UP ==========
    rm -f *.o
    rm -f $(name).map
    rm -f $(name)
    rm -f *.d
    # ========== DONE ==========



# include the contents of all the .d files
# note: the .d files contain:
# <filename>.o:<filename>.c plus all the dependancies for that .c file 
# I.E. the #include'd header files
# wrap with ifneg... so will not rebuild *.d files when goal is 'clean'
#
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEP)
endif

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 2019-08-30
    相关资源
    最近更新 更多