0

練習用にいくつかの純粋な C プログラムを作成しました。各小さなプログラムには、XXX.hファイルXXX.cfile とXXX_test.cmain 関数を含むファイルがあります。XXX.cファイルと の両方に、XXX_test.c他のYYY.hファイルが含まれている可能性があります。gcc -MM を使用して、XXX_test.cファイルの依存関係を自動的に見つけます。最後に、(GNU makefile を使用して) makefile を作成しますXXX.mk

# change your targets to your real targets
MINGW := MINGW32_NT-6.1
CC = gcc
OFLAG = -o 
CFLAGS = -Wall -g -DDEBUG
# get the dependent header files and change their name to source files
TARGET := XXX_test
FILES := $(filter %.c %.h, $(shell gcc -MM $(addsuffix .c, $(TARGET))))
SRCS := $(FILES:.h=.c)
DEPS := $(SRCS:.c=.d)
OBJECTS := $(SRCS:.c=.o)

#determine the os platform
ifdef SystemRoot
   ifeq ($(shell uname), ${MINGW})
      RM = rm -f
      FixPath = $1
   else
      RM = del /Q
      FixPath = $(subst /,\,$1)
   endif
else
   ifeq ($(shell uname), Linux)
      RM = rm -f
      FixPath = $1
   endif
endif


all: ${TARGET}
# include .d files generated by gcc -MMD opt
-include $(DEPS)
# to generate the .o files as well as the .d files
%.o:%.c
    $(CC) $(CFLAGS) -c -MMD $< -o $@

# generate the executable program
${TARGET}: ${OBJECTS}
    ${CC} $^ ${OFLAG} $@

.PHONY:clean
# the "$" is not needed before "FixPath"
clean:
    $(RM) $(call FixPath, ${OBJECTS} ${DEPS})

小さなプログラムごとにXXX.mkファイルがあります。変数の内容が異なることを除いて、それらはほとんど同じですTARGET(上記の makefile を参照)。XXX.mkなどがあります...私がYYY.mk聞きたい質問は、すべてのメイクファイル、つまり ... を 1 つのメイクファイルに変換するにはどうすればよいかということです。XXX.mkYYY.mkたとえば、 に割り当てられgeneric.mkた変数TARGETS( に注意してください) を使用します。私が扱いにくいと思うのは、次のとおりです。SXXX_test YYY_test ...variable dependencies

TARGET --> OBJECTS --> SRCS --> FILES --> TARGET(the FILES is generate by gcc using -MM opt)
                         ↓
                        DEPS(used to include the .d files)

各ターゲット (XXX_test など) は、一連のファイルに依存する必要があります。GNU makefile の威力を知りたいのですが、どうすればできますか? 私はgmakeの使い方を学んでいます。

4

2 に答える 2

2

お気づきのように、主な問題は、DEPS からの OBJECTS の展開が複数のターゲットでうまく機能しないことです。

これを解決する 1 つの可能性は、2 段階のアプローチを使用することです。2 段階目は単一のバイナリの構築のみを処理し (そしてすべての依存関係の追跡とバイナリ オブジェクトのコンパイルを行います)、1 段階目は指定されたバイナリごとに 2 番目のものを呼び出します。

この解決策には、2 つのMakefile が含まれます (要求されたものとは正確には異なりますが、それでもなお):

メイクファイル:

TARGETS = XXX_test YYY_test ZZZ_test XYZ_test
CLEANTARGETS=$(TARGETS:=_clean)

all: $(TARGETS)
clean: $(CLEANTARGETS)

$(TARGETS) $(CLEANTARGETS):
        make -f Makefile.sub $@

.PHONY: all clean $(CLEANTARGETS)

この makefile は、ビルドするプログラムを引数として別の make を呼び出し、2 番目の Makefile.sub を使用するだけです。

# change your targets to your real targets
MINGW := MINGW32_NT-6.1
CC = gcc
OFLAG = -o 
CFLAGS = -Wall -g -DDEBUG
# get the dependent header files and change their name to source files
TARGET=$(MAKECMDGOALS:_clean=)
FILES= $(filter %.c %.h, $(shell gcc -MM $(addsuffix .c, $(TARGET))))
SRCS= $(patsubst %.h,%.c,$(filter %.c %.h, $(shell gcc -MM $(addsuffix .c, $(TARGET)))))

DEPS= $(SRCS:.c=.d)
OBJECTS= $(SRCS:.c=.o)

#determine the os platform
ifdef SystemRoot
   ifeq ($(shell uname), $(MINGW))
      RM = rm -f
      FixPath = $1
   else
      RM = del /Q
      FixPath = $(subst /,\,$1)
   endif
else
   ifeq ($(shell uname), Linux)
      RM = rm -f
      FixPath = $1
   endif
endif


# include .d files generated by gcc -MMD opt
-include $(DEPS)
# to generate the .o files as well as the .d files
%.o:%.c
    $(CC) $(CFLAGS) -c -MMD $< -o $@

# generate the executable program
$(TARGET): $(OBJECTS)
    $(CC) $^ $(OFLAG) $@

.PHONY:clean
# the "$" is not needed before "FixPath"
clean:
    $(RM) $(call FixPath, $(OBJECTS) $(DEPS))

$(TARGET)_clean: clean

単一の Makefile を使用することに固執する場合は、依存関係の追跡を手動で行う必要があると思います。より一般的なビルドシステムの 1 つは autotools で、各バイナリのソースを自分で提供する必要があります (以下を実行するには、autotools をインストールする必要があります。実行して次のコードからautoreconf生成configureし、次に実行してクロスプラットフォームの Makefile を作成します) 。 :Makefile.in./configure

Makefile.am:

 bin_PROGRAMS = XXX_test YYY_test
 XXX_test_SOURCES = XXX_test.c XXX.c
 YYY_test_SOURCES = YYY_test.c YYY.c

configure.ac:

AC_INIT([XYZ],[0.1])
AM_INIT_AUTOMAKE($PACKAGE_NAME,$PACKAGE_VERSION)
AC_CONFIG_FILES([Makefile])
AC_PROG_INSTALL
AC_LANG_C
AC_PROG_CC
AC_OUTPUT
于 2013-01-23T17:40:29.243 に答える
-1

ターゲット/依存関係は複数の値を持つことができます。指定すれば

 TARGET := XXX_test XXY_test XYZ_test XZY_test

次に実行するmake allと (これがデフォルトですall。これは、Makefile の最初のターゲットであるためです。したがって、単純に実行することもできますmake)、これらすべての ???_test ファイルがビルドされます。

于 2013-01-23T11:56:37.863 に答える