标签: gnu-make

是否可以在Makefile中"取消设置"环境变量?

我正在使用GNU make,并且在项目中包含第三方库,如果CFLAGS在调用环境时在环境中定义了构建系统,则该系统会变得狂暴.我喜欢CFLAGS在我的环境中定义其他原因.正在从另一个makefile调用库的构建,所以我说例如:

的3rdParty: $(MAKE) -f Makefile.3rdparty

但是我想确保CFLAGS在第三方Makefile上调用make时没有设置.我能找到的最近的事情就是说:

CFLAGS:=

但是这仍然留CFLAGS在环境中,它只是一个空字符串.除了做一些可怕的事情,比如说:

的3rdParty: bash -c "unset CFLAGS; $(MAKE) -f Makefile.3rdparty"

是否有一种简单的方法可以CFLAGS从我的主要makefile中"取消设置" 变量,以便在调用第三方库时环境中根本不存在该变量?

makefile environment-variables gnu-make

19
推荐指数
1
解决办法
1万
查看次数

使用GNU Make同时构建调试和发布目标

我正在开发一个中型项目,其中包含几个具有相互依赖性的库,我最近将其转换为使用非递归makefile构建.我的下一个目标是同时从同一源代码树中构建调试和发布版本(make debug; make release).我的第一步是制作包含正确构建标志的调试和释放目标.我使用目标特定变量做到了这一点,如下所示:CXXFLAGS = -Wall -Wextra -Werror -DLINUX

CXX_DEBUG_FLAGS=-g3 -DDEBUG_ALL
CXX_RELEASE_FLAGS=-O3

.PHONY: debug 
debug: CXXFLAGS+=$(CXX_DEBUG_FLAGS) 
debug: build

.PHONY: release 
release: CXXFLAGS+=$(CXX_RELEASE_FLAGS) 
release: build
Run Code Online (Sandbox Code Playgroud)

这工作正常,但您只能同时构建调试或发布,而不是两者.同时,我并不是说在同一个构建过程中,我的意思是在同一个源代码树中背靠背(make debug; make release).为了做到这一点,我需要将目标文件放在一个特定于调试/发布的目录中,这样它们就不会相互覆盖,我需要用'D'来修改调试目标二进制文件名.我虽然这很容易,因为我可以再次使用目标特定变量,如下所示:CXXFLAGS = -Wall -Wextra -Werror -DLINUX

CXX_DEBUG_FLAGS=-g3 -DDEBUG_ALL
CXX_RELEASE_FLAGS=-O3

.PHONY: debug 
debug: CXXFLAGS+=$(CXX_DEBUG_FLAGS) 
debug: MODULE_BLD_TYPE=D
debug: OUT_DIR=debug_obj
debug: build

.PHONY: release 
release: CXXFLAGS+=$(CXX_RELEASE_FLAGS) 
release: MODULE_BLD_TYPE:=
release: OUT_DIR=release_obj
release: build

.PHONY: build
build: TARGET_NAME=HelloWorld$(MODULE_BLD_TYPE)
build: TARGET_BUILD_DIR=$(PROJECT_ROOT_DIR)/$(OUT_DIR)
build: TARGET_BUILD_OBJS=$(addprefix $(TARGET_BUILD_DIR)/,$(SOURCES:.cpp=.o))
build: $(TARGET_NAME)
Run Code Online (Sandbox Code Playgroud)

你让专家读这个已经知道这不会起作用,因为你不能使用目标特定变量来创建实际目标.它们对我的CXXFLAGS var工作正常,因为该变量未在目标名称中使用.

是否有使用非递归makefile管理调试/发布版本的设计模式和/或最佳实践?具体来说,如何构建目标文件目录路径和目标名称(根据目标构建目标)?

makefile gnu-make

18
推荐指数
1
解决办法
2万
查看次数

为什么GNU Make罐头食谱不起作用?

我期待看到下面的makefile创建的文件foo1foo3.但是只创建了一个文件foo3.对我而言,似乎罐头配方make-foo被make简单地忽略了.目标foo1foo2(空配方)的调试结果是相同的.

# why canned recipe doesn't work ?
# http://www.gnu.org/software/make/manual/make.html#Canned-Recipes
define make-foo =
echo making $@
touch $@
endef

.PHONY: all
all: foo1 foo2 foo3

# foo1 is not created, but why ?
.PHONY: foo1
foo1:
    $(make-foo)

# debug output similar to foo1
.PHONY: foo2
foo2:

# this works
.PHONY: foo3
foo3:
    echo making $@
    touch $@
Run Code Online (Sandbox Code Playgroud)

跑步:

xxxx@xxxx:/dev/shm$ make -dRr
GNU Make 3.81
Copyright (C) 2006  Free …
Run Code Online (Sandbox Code Playgroud)

gnu-make

18
推荐指数
1
解决办法
5093
查看次数

GNU将转换空间转换为冒号

给定以冒号分隔的路径列表,使用GNU Make获取以空格分隔的列表非常简单:

CPATHS := /usr/bin/foo:/usr/bin/baz:/usr/bin/baz
SPATHS := $(subst :, ,$(CPATHS))
Run Code Online (Sandbox Code Playgroud)

但是,我找不到朝着相反方向前进的好方法.以下hack确实有效(至少在安装了sed的情况下)但是我很确定只有使用Make的内部函数才能有更好的解决方法.

SPATHS := /usr/bin/foo /usr/bin/baz /usr/bin/baz
CPATHS := $(shell echo $(SPATHS) > tmp; sed 's/ \+/:/g' tmp; rm tmp)
Run Code Online (Sandbox Code Playgroud)

makefile space path gnu-make colon

18
推荐指数
2
解决办法
4363
查看次数

在Windows上进行(并行作业)

什么设置适用于GNU在Windows上进行并行作业(-j)?

我已经尝试使用MinGW make 3.81将shell设置为cmd.exe,这适用于创建多个进程但是使用"等待作业"消息失败.

这可以工作,什么是最好的设置?(MinGW/Cygwin/???)有人能指出一个可以测试的工作示例吗?

build-process makefile gnu-make

17
推荐指数
2
解决办法
1万
查看次数

GNU Make的多通配符模式规则

我想写一些像正则表达式:

SRC:="a.dat.1 a.dat.2"    
$(SRC): %.dat.%: (\\1).rlt.(\\2)    
      dat2rlt $^ $@
Run Code Online (Sandbox Code Playgroud)

这样a.dat.1a.dat.2将给出a.rlt.1a.rlt.2.

在GNU Make info页面中,它显示"%只能使用一次".

在GNU Make中有一些技巧可以实现吗?

design-patterns makefile gnu-make

17
推荐指数
2
解决办法
8623
查看次数

如何在Ubuntu下处理GNU Make中的shell扩展?

鉴于此非常简单Makefile:

all:
    @mkdir -pv test/{a,b}
Run Code Online (Sandbox Code Playgroud)

我在OS X 10.6.8和CentOS 5.5上得到了这个输出:

mkdir: created directory `test'
mkdir: created directory `test/a'
mkdir: created directory `test/b'
Run Code Online (Sandbox Code Playgroud)

但是在Ubuntu 11.04上我得到了这个:

mkdir: created directory `test'
mkdir: created directory `test/{a,b}'
Run Code Online (Sandbox Code Playgroud)

mkdir -pv test/{a,b}在所有平台上的shell中手动运行命令会产生预期的结果.

GNU Make的版本在所有平台上都是相同的:

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program is built for [PLATFORM]
Run Code Online (Sandbox Code Playgroud)

在Ubuntu下有什么不同,为什么shell扩展不在那里工作?

bash ubuntu makefile gnu-make brace-expansion

17
推荐指数
1
解决办法
4941
查看次数

测量Makefile的每个目标所花费的时间

Makefile当我这样做时,有没有办法回应递归的每个目标所花费的(系统,用户,真实)时间make all

我想以更细粒度的方式对项目的编译进行基准测试time make all.理想情况下,它会回显执行目标的树,每个树都有在其所有依赖项中花费的时间.如果它可以使用-j(并行制作)也会很棒.顺便说一下,我Makefile是非递归的(不会make为每个主要目标产生另一个实例).

谢谢!

benchmarking profiling makefile gnu-make

17
推荐指数
2
解决办法
6579
查看次数

makefile缺少分隔符

好吧,我坚持这个,我不知道我做错了什么.在一个更复杂的makefile上,一切都很好,但突然之间我得到了"Missing separator"错误.我能够将它分离到一个非常简单的场景:

test.mk

define push_dir
$(info ${1})
endef

define pop_dir
$(info ${1})
endef

define include_submake
$(call push_dir,${1})
$(call pop_dir,${1})
endef
Run Code Online (Sandbox Code Playgroud)

简单

include test.mk

INITIAL_SUBMAKE:= includeme.mk
$(call include_submake,${INITIAL_SUBMAKE})

process:
    @echo Processed...
Run Code Online (Sandbox Code Playgroud)

并输出:

C:\project>make -f Simple process
includeme.mk
includeme.mk
Simple:4: *** missing separator.  Stop.
Run Code Online (Sandbox Code Playgroud)

includeme.mk实际上并不存在.我不知道这里出了什么问题我尝试了很多东西.如果我将include_submake的调用包围在这样的信息中:

$(info $(call include_submake,${INITIAL_SUBMAKE}))
Run Code Online (Sandbox Code Playgroud)

丢失的分隔符错误消失了.另外如果在include_submake定义中我只调用其中一个函数,它工作正常.另外,如果我直接调用函数而不是调用它,include_submake它也可以正常工作:

include test.mk

INITIAL_SUBMAKE:= includeme.mk
$(call push_dir,${INITIAL_SUBMAKE})
$(call pop_dir,${INITIAL_SUBMAKE})

process:
    @echo Processed...


C:\project>make -f Simple process
includeme.mk
includeme.mk
Processed...
Run Code Online (Sandbox Code Playgroud)

我觉得我在这里忽略了一些基本的东西.谢谢你的帮助.

makefile syntax-error gnu-make

17
推荐指数
1
解决办法
3万
查看次数

如何在Makefile中定义全局shell函数?

我想定义一个shell函数

#!/bin/sh

test ()
{
  do_some_complicated_tests $1 $2;
  if something; then
    build_thisway $1 $2;
  else
    build_otherway $1 $2;
  fi
}
Run Code Online (Sandbox Code Playgroud)

以这种方式,我可以在我的Makefile的每个规则中使用它,例如:

foo: bar
  test foo baz
Run Code Online (Sandbox Code Playgroud)

要清楚,我希望shell函数成为Makefile的一部分.这样做最优雅的方法是什么?如果您可以在不递归调用make的情况下执行此操作,则可获得积分.


背景:我的实际问题是make -n产生一个非常长且不可读的输出.每个规则使用几乎相同的不可读shell命令序列,并且有许多规则.上述解决方案将使输出make -n更有用.

shell makefile sh gnu-make

17
推荐指数
6
解决办法
7241
查看次数