【问题标题】:Makefile for project with code in multiple directories but same directory structure具有多个目录但目录结构相同的项目的 Makefile
【发布时间】:2017-07-06 06:43:01
【问题描述】:

我的 C++ 项目的目录结构如下:

.
├── bin
├── build
├── include
│   ├── dir1
│   │   ├── file1.hpp
│   │   └── file2.hpp
│   ├── dir2
│   │   ├── file3.hpp
│   │   └── file4.hpp
│   └── third_party
│       └── catch.hpp
├── Makefile
├── src
│   ├── dir1
│   │   ├── file1.cpp
│   │   └── file2.cpp
│   └── dir2
│       ├── file3.cpp
│       └── file4.cpp
└── test
    ├── dir1
    │   ├── file1.test.cpp
    │   └── file2.test.cpp
    └── dir2
        ├── file3.test.cpp
        └── file4.test.cpp

如何编写 Makefile 来编译 srctest 目录中的代码并获取 build 目录中的目标文件和 bin 目录中的二进制文件,并在其中保持相同的目录结构, 无需明确命名每个文件及其依赖项?在srctest 中的每个dir* 中使用多个Makefile 会更好吗?

我的 Makefile 目前看起来像这样:(这可能是荒谬的,对此感到抱歉!)

binaries_dir = bin
build_dir = build
sources_dir = src
include_dir = include

compile_flags = -std=c++14 -Wall

binaries := $(wildcard *.out)
objects := $(wildcard *.o)
sources := $(wildcard *.cpp)
headers := $(wildcard *.hpp)

objects: $(sources)
    g++ $(compile_flags) -c $(sources_dir)/$(sources) -I $(include_dir)

binaries: $(objects)
    for object in $(objects); do
        g++ $(compile_flags) -o $(binaries_dir)/ $(build_dir)/$object
    done

【问题讨论】:

  • 我在latedev.wordpress.com/2014/11/08/… 有几篇(不完整的)文章,介绍了如何编写通用的 makefile,这可能有用也可能没用。
  • @NeilButterworth 这似乎很有用,谢谢!通过 ATM。
  • 这真的取决于你的目标程序是什么。这是否都构建了一个程序?还是每个源文件一个程序?
  • @Galik 每个源文件一个程序
  • 假设文件名将是唯一的,以便在bin 目录中的程序不会相互覆盖?或者您想要源目录中 bin 目录下的相同子目录?

标签: c++ makefile


【解决方案1】:

我不认为这是万无一失的,但我认为它几乎可以满足您的需求。您应该研究如何构建 Makefile,因为事实证明这不太适合您的需求,您将如何解决它?

CXX := g++
RM  := rm -f
MD  := mkdir -p

# don't change, this is for dependencies
CXXFLAGS += -MMD -MP

# add compiler flags here
CXXFLAGS += -std=c++14 -pedantic-errors
CXXFLAGS += -Wall -Wextra
CXXFLAGS += -g3 -O0

# add external includes here
CPPFLAGS += -Iinclude

# add library flags here
LDFLAGS +=

DIRS := $(patsubst  src/%, %, $(wildcard  src/*))
DIRS += $(patsubst test/%, %, $(wildcard test/*))
PROG_SOURCES := $(wildcard  src/*/*.cpp)
TEST_SOURCES := $(wildcard test/*/*.cpp)
OBJECTS := $(patsubst  src/%.cpp, build/%.o, $(PROG_SOURCES))
OBJECTS += $(patsubst test/%.cpp, build/%.o, $(TEST_SOURCES))
EXECUTABLES := $(patsubst  src/%.cpp, bin/%, $(PROG_SOURCES))
EXECUTABLES += $(patsubst test/%.cpp, bin/%, $(TEST_SOURCES))
DEPENDENCIES := $(patsubst   src/%.cpp, build/%.d, $(PROG_SOURCES)) 
DEPENDENCIES += $(patsubst  test/%.cpp, build/%.d, $(TEST_SOURCES)) 

all: dirs $(EXECUTABLES)

build/%.o: src/%.cpp
    $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<

build/%.o: test/%.cpp
    $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<

bin/%: build/%.o
    $(CXX) $(CXXFLAGS) -o $@ $< $(LDFLAGS)

-include $(DEPENDENCIES)

clean:
    @echo Removing build files
    @$(RM) $(EXECUTABLES) $(OBJECTS) $(DEPENDENCIES)

dirs:
    @$(MD) $(patsubst %, build/%, $(DIRS)) $(patsubst %, bin/%, $(DIRS))

.PHONY: show dirs

【讨论】:

  • 肯定会深入阅读手册以了解有关 Makefile 的更多信息。感谢您的帮助!
【解决方案2】:

您可能会从中找到一些灵感:https://github.com/jschmerge/DasBuild

【讨论】:

  • 也会看看这个。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 2017-12-21
  • 2020-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多