【问题标题】:Build file (Rake or Make?) for building a few simple libraries with common options?构建文件(Rake 或 Make?)用于构建一些具有常用选项的简单库?
【发布时间】:2014-01-22 00:58:04
【问题描述】:

所以,我有一组不同的 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 之类可以处理此问题的示例构建文件吗?

【问题讨论】:

    标签: c makefile rake build-process


    【解决方案1】:

    制作一个(或多个)模板文件,放在一个公共基础文件夹中,然后在每个项目目录中放置一个生成文件,该文件设置特定于正在构建的库的标志,并仅列出源文件。然后它包括通用的 makefile(s) 模板,其中包含隐式规则和变量,这些规则和变量采用本地标志进行构建。

    所以一个类似这样的结构:

    项目根 |-- 生成文件 | |-- 规则.mk | |-- 变量.mk | |-- exe.mk | `--lib.mk |-- 库A | |-- 生成文件 | `--(此库的其他来源和标头) |-- 库B | |-- 生成文件 | `--(此库的其他来源和标头) |-- 程序A | |-- 生成文件 | `--(此程序的其他来源和标题) `--程序B |-- 生成文件 `--(此程序的其他来源和标题)

    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)
    

    【讨论】:

      【解决方案2】:

      我最终用 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 中或在命令行上手动指定

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-17
        • 1970-01-01
        • 1970-01-01
        • 2021-11-16
        • 2010-12-30
        • 1970-01-01
        • 2010-10-12
        • 2012-07-08
        相关资源
        最近更新 更多