【问题标题】:Makefile conditional includeMakefile 条件包含
【发布时间】:2011-04-24 00:41:23
【问题描述】:

我正在尝试编写一个需要 ALSA 或 OSS 标头的应用程序。基本上,如果 /etc/oss.conf 不存在,我想将定义传递给编译器,因为这可能意味着 soundcard.h 标头不存在(请随时纠正我,我还是新手与 OSS 合作)。根据 OSS 文档,您可以像这样使用 include 指令:

include /etc/oss.conf
CFLAGS := -I$(OSSLIBDIR)/include/sys

一个问题。 OSS 支持是可选的,所以我想检查头文件是否存在,如果存在,将定义传递给编译器。问题是,AFAIK 无法检查文件是否存在于 makefile rule 之外。在规则内部,如果我使用 if 语句,出于某种原因,尝试设置 CFLAGS 不会改变它:

test: $(objects)
    @if [ -f ${OSS_CONFIG} ]; then \
    . ${OSS_CONFIG}; \
    CFLAGS+=" -I${OSSLIBDIR} -DUSE_OSS"; \
    fi
    @echo ${CFLAGS}

(上面只是输出CFLAGS的原始值,即使${OSS_CONFIG}存在。)当然,这非常丑陋,我想知道是否有更清洁的方法来做到这一点。还是我打算这样做会引发一场涉及小猫种族灭绝的全球灾难性事件?

哦,请不要告诉我使用 autoconf。

【问题讨论】:

  • 不幸的是,这种事情是最初创建被称为“autoconf”的可恶系统的原因。在 autoconf 之前,您将手工制作一个 config 脚本,如果您精通 /bin/sh 的通用子集方言,这很容易做到,该方言适用于您的代码可能运行的每个类 unix 平台。很多人仍然发誓要手工制作自己的配置脚本……我还听说 CMAKE 是另一种出路,但对它的了解还不够,无法以此为基础。
  • 我强烈推荐 CMake。好东西。

标签: c makefile alsa open-source


【解决方案1】:

一个建议:使用-include(然后它不会警告+失败时退出)。不过,我不知道自己是否完全掌握了这种语法。

另一个 hack 可能类似于:DUMMY_VAR := $(shell ... ) 来执行任意代码。我认为这更不可能奏效。

除此之外,我认为这是可能的。最近在研究类似的问题时,发现在makefile创建过程中无法让make运行任意shell命令。

【讨论】:

  • 哇,我完全不知道-include。非常感谢你,这几乎解决了我的问题。我可以在包含之后使用ifdef OSSLIBDIR,然后相应地分配CFLAGS。荣誉。
【解决方案2】:

是的,有一种更清洁的方法。您可以使用wildcard 函数测试文件是否存在,然后使用ifeq/endif 设置适当的CFLAGS。如果您将与音频相关的标志粘贴到 AUDIO_CFLAGS 之类的东西中,那么您可以在整个 Makefile 中自动包含正确的标志集。

它看起来像这样:

OSS_CONF_FILE := $(strip $(wildcard /etc/oss.conf))

ifeq ($OSS_CONF_FILE,)
    AUDIO_CFLAGS = "-I${ALSALIBDIR} -DUSE_ALSA"
else 
    AUDIO_CFLAGS = "-I${OSSLIBDIR} -DUSE_OSS"
endif


sample_build_rule:
    $(CC) $(CFLAGS) $(AUDIO_CFLAGS) ...

【讨论】:

  • 这也行得通,虽然我认为我会坚持使用-include 并使用ifdef 只是为了清楚起见。为特定于库的 CFLAGS 使用单独的变量很好,我想我会使用它。
  • 这很好,也几乎解决了我的问题。出于好奇,您知道是否有办法在 makefile 中使用 foreach 循环?具体来说,我想做类似的事情:foreach DIR in ( ls ) -include DIR/Rules.mk
  • include 将采用多个文件并扩展通配符。 -include */Rules.mk 不适合你吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
相关资源
最近更新 更多