src
私は、すべてのサブディレクトリでソースコードファイルを含むディレクトリを検索し、オブジェクトをコンパイルするMakefileに取り組んでいます。後でbin
、Makefileと同じディレクトリ内のディレクトリにあるバイナリにオブジェクトをリンクします。各バイナリは、オブジェクトファイルをリンクしたサブディレクトリにちなんで名付けられます。これがやや紛らわしいように聞こえたらごめんなさい...
これが私が何を意味するかを示す図です:
Makefile
app1-\
src-\
main.c
obj-\
main.o
app2-\
src-\
main.c
obj-\
main.o
bin-\
app1
app2
現時点では、Makefileを実行すると、オブジェクトファイルは正常にコンパイルされますが、それらをリンクする場合は、すべてを最初のバイナリにリンクしようとします。
エラー:
Generating dependencies for problem2.1/src/2-1.c...
Compiling problem2.1/src/2-1.c...
Generating dependencies for problem2.1/src/2-1.c...
Compiling problem2.1/src/2-1.c...
Linking bin/problem2.1...
./problem2.2/obj/2-2.o: In function `main':
/cygdrive/c/Users/Hans/git/opsys/task_01/problem2.1/src/2-1.c:9: multiple definition of `_main'
./problem2.1/obj/2-1.o:/cygdrive/c/Users/Hans/git/opsys/task_01/problem2.1/src/2-1.c:9: first defined here
collect2: ld returned 1 exit status
Makefile:57: recipe for target `bin/problem2.1' failed
make: *** [bin/problem2.1] Error 1
ここでの主な問題は、Makefilesについて何かを誤解していることだと思いますが、私がやろうとしていることを実行する方法はありますか?
これまでのところ、これに似ているのはmakeの再帰機能を使用することだけですが、これが唯一の方法ですか?
私のMakefile:
SRCEXT = c
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SUBDIRS := $(shell find . -type d -name '*$(SRCDIR)*' -exec dirname {} \; | uniq)
SRCDIRS := $(shell find $(SUBDIRS) -name '*.$(SRCEXT)' -exec dirname {} \; | uniq)
OBJDIRS := $(subst src,obj,$(SRCDIRS))
SRCS := $(shell find $(SRCDIRS) -name '*.$(SRCEXT)')
OBJREF := $(subst src,obj,$(SRCS))
OBJS := $(patsubst %.$(SRCEXT),%.o,$(OBJREF))
APPS := $(subst ./,,$(SUBDIRS))
DEBUG = -g
CFLAGS = -Wall -pedantic -ansi -c $(DEBUG) $(INCLUDES)
ifeq ($(SRCEXT), cpp)
CC = $(CXX)
else
CFLAGS += -std=gnu99
endif
.PHONY: all clean distclean
all: $(BINDIR)/$(APPS)
$(BINDIR)/$(APPS): buildrepo $(OBJS)
@mkdir -p `dirname $@`
@echo "Linking $@..."
@$(CC) $(OBJS) $(LDFLAGS) -o $@
$(OBJS): $(SRCS)
@echo "Generating dependencies for $<..."
@$(call make-depend,$<,$@,$(subst .o,.d,$@))
@echo "Compiling $<..."
@$(CC) $(CFLAGS) $< -o $@
clean:
$(RM) -r $(OBJDIRS)
distclean: clean
$(RM) -r $(BINDIR)
buildrepo:
@$(call make-repo)
define make-repo
for dir in $(OBJDIRS); \
do \
mkdir -p $$dir; \
done
endef
# usage: $(call make-depend,source-file,object-file,depend-file)
define make-depend
$(CC) -MM -MF $3 -MP -MT $2 $(CFLAGS) $1
endef