Makefile在多个目录中

yau*_*ser 8 makefile

我想构建一个应用程序,我有多个模块存储在多个目录中.我决定遵循这个想法,即在每个目录中都有一个makefile然后合并它.但是 - 作为初学者程序员 - 我仍然没有看到如何做到这一点.首先,这种"部分"的makefile是怎样的.它们不能具有main函数,因为每个二进制文件只能有一个,但是当我尝试编译它时,gcc会抱怨对main的未定义引用.其次,我不知道如何将所有这些模块组合在一起.

我将不胜感激,但请尽量保持简单的答案.Makefile对我来说仍然是一个黑魔法.

Bet*_*eta 26

在使用makefile执行任何操作之前,必须知道如何在没有makefile的情况下执行此操作.

由于您使用的是gcc,我假设您的源代码是C++.

你还没有告诉我们您的目录结构是什么样子,所以我会假设你有两个目录三个源文件:primary/main.cc,other/foo.ccother/bar.cc.(我们可以像foo.h以后一样处理头文件.)你想要构建myApp.

第1步:手工完成

要在一个命令中执行此操作,您可以使用:

gcc -Wall primary/main.cc other/foo.cc other/bar.cc -o myApp
Run Code Online (Sandbox Code Playgroud)

这将编译三个源文件并将二进制对象链接到可执行文件中myApp.

第2:在片中进行操作(在完成上一步之前,不要尝试这样做.)

您可以采用中间步骤,将源文件编译为二进制对象文件,而不是使用一个命令构建:

gcc -Wall -c primary/main.cc -o primary/main.o
gcc -Wall -c other/foo.cc -o other/foo.o
gcc -Wall -c other/bar.cc -o other/bar.o
Run Code Online (Sandbox Code Playgroud)

这将产生alpha/main.o,beta/foo.obeta/bar.o.编译器不会抱怨foobar缺少main()函数,因为目标文件不需要.然后将对象链接到一个可执行文件:

gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp
Run Code Online (Sandbox Code Playgroud)

第3:在本地进行操作(在完成上一步操作之前,请不要尝试此操作.)

就像上一步一样,但我们采取行动primary/并且other/:

cd primary
gcc -Wall -c main.cc -o main.o
cd ../other
gcc -Wall -c foo.cc -o foo.o
gcc -Wall -c bar.cc -o bar.o
cd ..
gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp
Run Code Online (Sandbox Code Playgroud)

第4:使用Makefile(不要尝试这个,直到你可以让上一步完美地工作.)

我们可以让makefile执行第1步,但这不是必需的.在primary(即primary/makefile)中写一个makefile,如下所示:

main.o:
    gcc -Wall -c main.cc -o main.o
Run Code Online (Sandbox Code Playgroud)

(从中获取的空白gcc...是TAB.)

现在试试这个:

cd primary
make
cd ../other
gcc -Wall -c foo.cc -o foo.o
gcc -Wall -c bar.cc -o bar.o
cd ..
gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp
Run Code Online (Sandbox Code Playgroud)

第5:使用多个Makefile(不要尝试这个,直到你可以让上一步完美地工作.)

写一个other/makefile:

both: foo.o bar.o

foo.o:
    gcc -Wall -c foo.cc -o foo.o

bar.o:
    gcc -Wall -c bar.cc -o bar.o
Run Code Online (Sandbox Code Playgroud)

和顶层目录中的makefile,您正在构建myApp:

myApp:
    gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp
Run Code Online (Sandbox Code Playgroud)

现在试试这个:

cd primary
make
cd ../other
make
cd ..
make
Run Code Online (Sandbox Code Playgroud)

第6:使用一个调用其他人的Makefile(不要尝试这个,直到你可以让上一步完美地工作.)

编辑顶级makefile:

myApp:
    cd primary; make
    cd other; make
    gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp
Run Code Online (Sandbox Code Playgroud)

现在尝试:

make
Run Code Online (Sandbox Code Playgroud)

如果所有这些都有效,那么你拥有的是一个原始但有效的 makefile系统.当您准备好取下训练轮时,有许多可能的改进.

编辑:

如果子目录中有许多源文件(例如other/)并且您不想手动在顶部makefile中维护列表,则有几种方法可以处理它.这是一:

OTHER_SOURCES := $(wildcard other/*.cc)

OTHER_OBJECTS := $(OTHER_SOURCES:.cc=.o)

myApp:
    cd primary; make
    cd other; make
    gcc -Wall primary/main.o $(OTHER_OBJECTS) -o myApp
Run Code Online (Sandbox Code Playgroud)

但是在尝试更精简之前,你应该让这些makefile工作并理解它们.