所以,我在C和C ++中有一组不同的库,我需要用一些常见的选项来构建它们。我当前的“模板”makefile看起来像这样:
#Change this for different MCUs. Standard includes atmega328
VARIANT = ../variants/standard
HDRS=RedBot.h
OBJS=RedBot.o RedBotAccel.o RedBotMotor.o RedBotSensor.o
CPPFLAGS = -I../arduino/ -I./ -DF_CPU=16000000UL -Os -mmcu=atmega328p
CC=avr-gcc
CPP=avr-g++
AR=avr-ar
default: libredbot.a
libredbot.a: ${OBJS}
${AR} crs libredbot.a $(OBJS)
.c.o: ${HDRS}
${CC} -I ${VARIANT} ${CFLAGS} -c $*.c
.cpp.o: ${HDRS}
${CPP} -I ${VARIANT} ${CPPFLAGS} -c $*.cpp
clean:
rm -f ${OBJS} core a.out errs *.a
我将makefile放在与所有源相同的文件夹中。然而,由于一些原因,这是丑陋的。首先,它只是一个模板。我必须在大约15个库中复制这个。我需要编译选项在所有库中都很容易更改,因为多个目标很常见。目前,我能想到的最好的事情是使用传递给每个库makefile的选项创建一个根makefile。但是,我仍然需要跟踪所有文件(OBJS
位)。并非所有库都能够在所有目标上构建。
有人可以指向一个更全面的makefile,或者可能是像Rake这样可以处理这个问题的示例构建文件吗?
答案 0 :(得分:0)
制作一个(或多个)模板文件放在一个公共基础文件夹中,然后在每个项目目录中放置一个makefile,它设置特定于正在构建的库的标志,以及仅列出源文件。然后它包含常见的makefile(s)模板,其中包含隐式规则和带有本地标志的变量。
这样的结构是这样的:
project root |-- makefiles | |-- rules.mk | |-- vars.mk | |-- exe.mk | `-- lib.mk |-- libraryA | |-- Makefile | `-- (other sources and headers for this library) |-- libraryB | |-- Makefile | `-- (other sources and headers for this library) |-- programA | |-- Makefile | `-- (other sources and headers for this program) `-- programB |-- Makefile `-- (other sources and headers for this program)
rules.mk
包含clean
等规则或.c.o
等隐式构建规则。
vars.mk
包含全局变量,并使用局部标志变量来设置全局标志变量,如CFLAGS
。
exe.mk
包含制作可执行程序的规则。
lib.mk
包含制作图书馆的规则。
本地makefile将如下所示:
LOCAL_CFLAGS = <some C flags specific to just this library/executable>
# Other local flags, e.g. LOCAL_LDFLAGS, LOCAL_LIBS, etc.
TARGET = <name of target executable/library>
LOCAL_SOURCES = <list of all source files for $(TARGET)>
LOCAL_HEADERS = <list of all headers>
include ../makefiles/vars.mk
include ../makefiles/rules.mk
include ../makefiles/exe.mk # If making an executable
include ../makefiles/lib.mk # If making a library
# Note: Don't include both the above two files
vars.mk
文件看起来像这样
CFLAGS = <some common C flags>
CFLAGS += $(LOCAL_CFLAGS)
# All other flag variables
HEADERS = $(LOCAL_HEADERS)
CFILES = $(filter %.c,$(LOCAL_SOURCES))
CXXFILES = $(filter %.cpp,$(LOCAL_SOURCES))
OBJECTS = $(CFILES:%.c=%.o)
OBJECTS += $(CFILES:%.cpp=%.o)
答案 1 :(得分:0)
我最后用Ruby编写了自己的小东西,以便轻松完成。你可以在这里汲取灵感:https://github.com/Earlz/make-wiring/blob/master/build.rb
基本上,它由一个带有许多环境变量的“模板”makefile组成。 build.rb脚本只是将它们传递给makefile,而无需在命令行上手动指定所有内容。因此使用情况如此:
./build.rb build redbot
./build.rb build arduino
或者其他什么,并且所有标志和参数都整齐地包含在build.rb中,而不是在几十个makefile之间传播或者在命令行中手动指定