生成make文件的最佳实践 [英] Best practice for building a make file

查看:66
本文介绍了生成make文件的最佳实践的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:

我对Make还是比较陌生,所以我开始为我最近制作的Othello游戏创建一个makefile.我当前的makefile比较简单.但是,我希望进一步完善它,并添加一个构建和存档功能.

I am relatively new to Make and I started building a makefile for my Othello game I recently built. My current makefile is relatively simple. Yet I am looking to refine it further and add a build and archive feature.

问题1: 为什么不打扫工作?

Question 1: Why doesn't clean work?

问题2: 对于归档,我计划使用

Question 2: For Archiving I plan on using

# tar cvzf *.o Othello

进行存档时,将编译时生成.o和可执行文件.这是一种好的标准做法还是有更好的方法呢?

to archive, the .o and executable generated when compiled. Is this a good standard practice or is there a better way to do this?

问题3: 对于构建部分,我计划使用./Othello运行可执行文件,这是在Makefile中进行构建的最佳实践吗?

Question 3: For the build portion, I plan on running the executable using ./Othello is this best practice for build in a makefile?

下面发布了git存储库,谢谢您的宝贵时间

The git repository is posted below thank you for your time

全部:奥赛罗

Othello: main.o Myothello.o space.o game.o
        clang++ main.o Myothello.o space.o game.o -o Othello

main.o: main.cc
        clang++ -c main.cc

game.o: game.cc
        clang++ -c game.cc

Myothello.o: Myothello.cc
            clang++ -c Myothello.cc

space.o: space.cc
        clang++ -c space.cc

clean:
rm -f *.o core *.core
rm MyOthello

推荐答案

这是为您提供的示例makefile,已在github项目上进行了测试.

Here is an example makefile for you, tested on your github project.

功能:

  1. 自动生成依赖项.
  2. 更改Makefile时自动重建.
  3. Debug/release构建在不同的目录中.调试版本是默认版本,对于发布版本,请使用make BUILD=release.
  4. 支持gccclang. gcc是默认设置,对于clang使用make COMPILER=clang.
  5. clean目标通过删除整个构建目录来工作.
  6. run目标以构建和运行,例如make run_othello.
  1. Automatic dependency generation.
  2. Automatic rebuild when Makefile is changed.
  3. Debug/release builds in different directories. Debug build is the default, use make BUILD=release for release builds.
  4. Supports gcc and clang. gcc is the default, use make COMPILER=clang for clang.
  5. clean target works by removing the entire build directory.
  6. run target to build and run, e.g. make run_othello.

限制:

  1. 假定所有源文件都在同一目录中.在更大的项目中,将有多个目录,每个目录具有多个构建目标(可执行库,静态库或共享库).需要一个同构的构建目录结构来支持此功能.完全可行,但是在下面的示例Makefile中需要更多的复杂性,因此为了简洁起见,省略了它.
  1. Assumes that all source files are in the same directory. In a bigger project there are going to be multiple directories each with multiple build targets (executable, static or shared library). An isomorphic build directory structure is required to support this. Which is totally doable but requires more complexities in example Makefile below, so that it omitted for brevity.

归档时,您可能只希望归档源文件和Makefile.无需包含任何构建工件(例如目标文件,库和可执行文件).

When archiving you may like to archive only the source files and the makefile. No need to include any build artefacts (like object files, libraries and executables).

# ==== Begin prologue boilerplate.
all : # The canonical default target.
BUILD := debug
build_dir := ${CURDIR}/${BUILD}
exes := # Executables to build.
# ==== End prologue boilerplate.

# ==== Begin define executable othello.
exes += othello
objects.othello = main.o game.o Myothello.o space.o
-include ${objects.othello:%.o=${build_dir}/%.d} # Include auto-generated dependencies.
# ==== End define executable othello.

# ==== Begin define another executable.
# ... as for othello
# ==== End define another executable.

# ==== Begin rest of boilerplate.
SHELL := /bin/bash
COMPILER=gcc

CXX.gcc := /bin/g++
CC.gcc := /bin/gcc
LD.gcc := /bin/g++
AR.gcc := /bin/ar

CXX.clang := /bin/clang++
CC.clang := /bin/clang
LD.clang := /bin/clang++
AR.clang := /bin/ar

CXX := ${CXX.${COMPILER}}
CC := ${CC.${COMPILER}}
LD := ${LD.${COMPILER}}
AR := ${AR.${COMPILER}}

CXXFLAGS.gcc.debug := -Og -fstack-protector-all
CXXFLAGS.gcc.release := -O3 -march=native -DNDEBUG
CXXFLAGS.gcc := -pthread -std=gnu++14 -march=native -W{all,extra,error} -g -fmessage-length=0 ${CXXFLAGS.gcc.${BUILD}}

CXXFLAGS.clang.debug := -O0 -fstack-protector-all
CXXFLAGS.clang.release := -O3 -march=native -DNDEBUG
CXXFLAGS.clang := -pthread -std=gnu++14 -march=native -W{all,extra,error} -g -fmessage-length=0 ${CXXFLAGS.clang.${BUILD}}

CXXFLAGS := ${CXXFLAGS.${COMPILER}}
CFLAGS := ${CFLAGS.${COMPILER}}

LDFLAGS.debug :=
LDFLAGS.release :=
LDFLAGS := -fuse-ld=gold -pthread -g ${LDFLAGS.${BUILD}}
LDLIBS := -ldl

COMPILE.CXX = ${CXX} -c -o $@ ${CPPFLAGS} -MD -MP ${CXXFLAGS} $(abspath $<)
PREPROCESS.CXX = ${CXX} -E -o $@ ${CPPFLAGS} ${CXXFLAGS} $(abspath $<)
COMPILE.C = ${CC} -c -o $@ ${CPPFLAGS} -MD -MP ${CFLAGS} $(abspath $<)
LINK.EXE = ${LD} -o $@ $(LDFLAGS) $(filter-out Makefile,$^) $(LDLIBS)
LINK.SO = ${LD} -shared -o $@ $(LDFLAGS) $(filter-out Makefile,$^) $(LDLIBS)
LINK.A = ${AR} rsc $@ $(filter-out Makefile,$^)

all : ${exes:%=${build_dir}/%} # Build all exectuables.

.SECONDEXPANSION:
# Build an executable.
${exes:%=${build_dir}/%} : ${build_dir}/% : $$(addprefix ${build_dir}/,$${objects.$$*}) Makefile | ${build_dir}
    $(strip ${LINK.EXE})

# Run an executable. E.g. make run_othello
${exes:%=run_%} : run_% : ${build_dir}/%
    @echo "---- running $< ----"
    /usr/bin/time --verbose $<

# Create the build directory on demand.
${build_dir} :
    mkdir $@

# Compile a C++ source into .o.
# Most importantly, generate header dependencies.
${build_dir}/%.o : %.cc Makefile | ${build_dir}
    $(strip ${COMPILE.CXX})

# Compile a C source into .o.
# Most importantly, generate header dependencies.
${build_dir}/%.o : %.c Makefile | ${build_dir}
    $(strip ${COMPILE.C})

clean :
    rm -rf ${build_dir}

.PHONY : clean all run_%

# ==== End rest of boilerplate.

这篇关于生成make文件的最佳实践的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆