Makefile:子目录和类似的文件名

时间:2018-01-05 17:04:50

标签: makefile

切换到Visual Studio Code以了解C / C ++ dev工具并停止依赖IDE。我尝试将Makefile用于此目的,因为它允许在目标设备上通过命令行运行编译(没有GUI ==没有IDE)。到目前为止,我已经设法制作了一个通用的Makefile,它将所有.cpp个文件编译成相应的.o文件,然后将它们全部链接在一起。它适用于将所有源存储在单个目录中的小项目。现在我必须移植我正在运行的Xcode项目。

问题是源文件存储在目录树(没有单个目录)中,可能同时是CC++。某些文件具有相似的文件名但位于不同的文件夹中。从C ++的角度来看,它意味着类具有相同的名称,但具有不同的名称空间。各种IDE可以轻松处理这个问题,但Makefile给我带来了各种各样的问题,因为我还不是一个制作大师。

我试图在每个目录中创建Makefile(我失败了),但后来我读到这被认为是一种糟糕的方法,所以我切换到单个Makefile方法。有人说我应该切换到CMake,但我认为没有首先理解Makefile创建是没有意义的,因为CMake最终会创建一个。它还允许在没有CMake和其他酷工具的设备上构建和安装(例如,如果没有Internet连接可以下载CMake)。

这是一个基本想法:

- project-name/
  - application/
    - core/
      - loader.hpp
      - loader.cpp
      - ...
    - loader.hpp
    - loader.cpp
    - ...
  - hardware/
    - loader.hpp
    - loader.cpp
    - ...
  - some-c-library
    - library.h
    - library.c
    - ...
  - main.cpp
- project-name.xcodeproj
- Makefile

TR& DL:无法制作复杂的Makefile。 GNU手册很难理解,在线博客/教程大多只涉及基本内容。

1 个答案:

答案 0 :(得分:2)

我真的不确定你是否需要过于复杂。当然,你可以让你的目录树中的Makefile搜索每个C和C ++文件,但是如果你添加了一个你不想编译的新文件呢?

尽管如此,你可以让事情变得更轻松。将源文件列表分配给变量 - 这样您就可以在需要时引用它们。

CPPSOURCES=hardware/loader.cpp application/core/loader.cpp main.cpp
CSOURCES=some-c-library/library.c

然后你将这些文件名转换为目标文件名 - 这只是用.o等替换.cpp ......

CPPOBJS=$(CPPSOURCES:.cpp=.o)
COBJS=$(CSOURCES:.c=.o)

还有一些标准变量用于指定传递给C ++和C编译器的标志

CXXFLAGS-g
CFLAGS-g

然后你有一个规则来构建你的项目。 $@是规则构建的东西的名称(即“myproject”),$^是依赖项列表。

myproject: $(COBJS) $(CPPOBJS)
   $(CXX) $(CXXFLAGS) -o $@ $^

Make附带了一堆默认规则,以便它已经知道如果你要求它构建“some / where / deep / in / my / project / somefile.o”它正在寻找“some / where / deep” /in/my/project/somefile.cpp“例如。

您可以添加规则来删除所有目标文件 - 这就是为什么使用变量很方便

clean:
    rm $(COBJS) $(CXXOBJS)

你唯一需要担心的是依赖关系,比如下面的例子告诉make它需要在“hardware / loader.hpp”或“application / core /”时构建“hardware / loader.o” loader.hpp“更新。

hardware/loader.o: hardware/loader.hpp application/core/loader.hpp

这可能是您想要自动调查生成的一个区域,因为它很容易错过依赖项,然后它不会在标题中拾取任何更改。如注释中所述,当您使用-M命令行选项构建代码时,gcc / g ++可以为您生成文件,您可以使用Makefile中的include指令添加它们。