Makefile:“_start”的多重定义

Makefile: multiple definition of '_start'

我的 makefile 有问题。

eos$ make
gcc objects.o -o bumper_cars
objects.o: In function `_start':
(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o:(.text+0x0): first defined here
objects.o: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crti.o:(.fini+0x0): first defined here
objects.o:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o:(.rodata.cst4+0x0):     first defined here
objects.o: In function `__data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o:(.data+0x0): first defined here
objects.o:(.rodata+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/crtbegin.o:(.rodata+0x0): first defined here
objects.o: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crti.o:(.init+0x0): first defined here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/crtend.o:(.dtors+0x0): multiple definition of     `__DTOR_END__'
objects.o:(.dtors+0x8): first defined here
/usr/bin/ld: warning: Cannot create .eh_frame_hdr section, --eh-frame-hdr ignored.
/usr/bin/ld: error in objects.o(.eh_frame); no .eh_frame_hdr table will be created.
collect2: ld returned 1 exit status

和生成文件:

CC =  gcc
CFLAGS = -Wall -std=c99 -g -pthread

all: objects.o bumper_cars

objects.o: bumper_cars.c sleeper.c sleeper.h
    $(CC) $(CFLAGS) $^ -o $@ -c

bumper_cars: objects.o
    $(CC) $^ -o $@

clean:
    rm -f bumper_cars.o
    rm -f bumper_cars

make 正在执行以下操作:

  1. bumper_cars.c 编译成已定义 main 的目标代码。
  2. 然后它将 sleeper.c 编译成目标代码,该代码也定义了 main

然后 make 将两个对象结合起来形成二进制文件,问题是链接器因为重复的 main 函数而抱怨。

注释掉或#ifdef 删除任一文件中的函数,然后重新发布make

这里是 link 您可能想了解的有关 make 实用程序的所有信息:http://www.gnu.org/software/make/manual/make.html

发布的 make 文件有一些错误。其中一个问题是多个 *.c 文件不会生成一个 .o 文件,而是会生成多个 .o 文件。

库文件仅在link步中使用 头文件​​仅在以下编译步骤中使用,几乎所有编译器警告都已启用。

我建议使用这个:

CC     :=  gcc
CFLAGS := -Wall -Wextra -pedantic -std=c99 -g
LIBS   := -lpthread
RM     := rm -f

.PHONY: all clean

NAME := bumper_cars
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)

all: $(OBJS) $(NAME)

#
# link the .o files into the target executable
#
$(NAME): $(OBJS)
    $(CC) $^ -o $@ $(LIBS)

#
# compile the .c file into .o files using the compiler flags
#
%.o: %.c sleeper.h
    $(CC) $(CFLAGS) -c $< -o $@ -I.


clean:
    $(RM) *.o
    $(RM) bumper_cars