标签: gnu-make

GNU Make的平面对象文件目录结构输出

我有一个使用GNU Make的C++小项目.我希望能够打开以下源文件:

src/
  a.cpp
  b/
    b.cpp
  c/
    c.cpp
Run Code Online (Sandbox Code Playgroud)

进入以下输出结构(此时我不关心重复):

build/
  a.o
  b.o
  c.o
Run Code Online (Sandbox Code Playgroud)

到目前为止,我有以下内容,不幸的是,将.o和.d放在每个.cpp旁边:

OBJS            :=      $(foreach file,$(SRCS),$(file).o)
DEPS            :=      $(patsubst %.o,%.d,$(OBJS))
sinclude $(DEPS)

$(OBJS) : %.o : %.cpp
        @echo Compiling $<
        $(CC) $(CC_FLAGS) $(INCS) -MMD -o $@ $<  
Run Code Online (Sandbox Code Playgroud)

我知道$(notdir ...)函数,但此时我用它来过滤对象的努力失败了.任何人都可以对此有所了解吗?这似乎是合理的事情.

makefile gnu-make

9
推荐指数
1
解决办法
8154
查看次数

如何在Makefile中定义规则,只编译被修改的*.cpp文件(及其依赖项),而不是所有*.cpp文件

让我们说我有文件:

库:

  • one.cpp,one.h
  • two.cpp,two.h
  • three.cpp,three.h

程序:

  • program.cpp

有没有办法,创建Makefile只会编译从上次编译修改的*.cpp?

目前我有类似的东西:

SRCS = one.cpp two.cpp three.cpp
OBJS = $(SRCS:.cpp=.o)

all: $(OBJS) program

.cpp.o:
    g++ -Wall -c $<

program:
    g++ -Wall $(OBJS) program.cpp -o program

clean:
    rm -f $(OBJS) program
Run Code Online (Sandbox Code Playgroud)

我工作正常,但是当我编译我的程序然后更改two.cpp或two.h时我需要首先运行"make clean",因为当我第二次运行"make"时,我得到:

Nothing to be done for 'all'.
Run Code Online (Sandbox Code Playgroud)

我想以这种方式更改我的Makefile,它会识别我的更改并重新编译该文件及其依赖项(如果one.cpp使用来自two.cpp的代码,这些代码已被修改,两个文件都应该重新编译).

所以如果我修改two.cpp,make应该这样做:

g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
Run Code Online (Sandbox Code Playgroud)

但是如果one.cpp使用了被修改的two.cpp中的代码,那么请执行以下操作:

g++ -Wall -c one.cpp
g++ -Wall -c two.cpp
g++ -Wall $(OBJS) program.cpp -o program
Run Code Online (Sandbox Code Playgroud)

makefile gnu-make

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

使用makefile和静态模式规则进行树构建

我正在研究一些在ARM上运行的裸机嵌入式代码,因此必须处理整个ARM与THUMB模式的区别.当前构建系统使用静态模式规则来确定是以ARM还是THUMB模式编译文件.

$(ACOBJS) : %.o : %.c
    @echo
    $(CC) -c $(CFLAGS) $(AOPT) -I . $(IINCDIR) $< -o $@
$(TCOBJS) : %.o : %.c
    @echo
    $(CC) -c $(CFLAGS) $(TOPT) -I . $(IINCDIR) $< -o $@
Run Code Online (Sandbox Code Playgroud)

其中ACOBJS是应该处于ARM模式的输出对象列表,对于TCOBJS和Thumb模式是相同的.这些列表是以通常的方式从源列表创建的

ACOBJS   = $(ACSRC:.c=.o)
TCOBJS   = $(TCSRC:.c=.o)
Run Code Online (Sandbox Code Playgroud)

目前,这导致构建中的目标文件散布在源树上,我并不特别希望这样.我一直试图在树构建中设置它,但却无法使其工作.我不一定需要充分利用树构建工作,但我希望至少能够使用输出目录,在该目录下所有中间文件最终都会运行.在这些限制条件下实现这一目标的最佳策略是什么?

我正在考虑的一个选项是使用automake或整个autotools工具链来构建一个makefile.这似乎支持创建我想要的makefile类型,但看起来有点矫枉过正.设计用于便携式构建的自动工具和裸机嵌入式系统之间似乎存在固有的阻抗不匹配,其中主机元组之类的东西由目标微观元素决定.

build-process makefile gnu-make

9
推荐指数
1
解决办法
6366
查看次数

Makefile模式规则失败?

使用GNU-make时,我的Makefile有一些模式规则:

%.o:%.c
    gcc $< -o:$@
Run Code Online (Sandbox Code Playgroud)

这个规则由我添加.

但是当我确实犯了它时会给出一个错误,说没有规则来制作目标%.o并且不会构建目标.

有时,还有其他行为.当我说第一次做时它没有构建目标(它给出错误说没有规则来制作目标),但是当我说立即再次制作时,它确实构建正确.

因此,当我明确指定每个源文件时,它会首次自行构建目标.

编辑:我在Centos上使用GNU-make(v6.3我猜,不确定).这可能是一些权限/用户ID /组ID问题吗?

有什么指示可以了解可能发生的事情和解决方案吗?

谢谢,-AD.

gnu-make

9
推荐指数
2
解决办法
7979
查看次数

make:在先决条件中使用目标特定变量

我正在尝试编写一个使用目标特定变量的先决条件的Makefile

version=

target1: override version=1
target1: package

target2: override version=2
target2: package

package: dir=package-${version}\
package: source

source: src/${version}.c
Run Code Online (Sandbox Code Playgroud)

当我运行make时,版本变量在目标包中,源为空.

我做错了什么?

makefile gnu-make

9
推荐指数
1
解决办法
4248
查看次数

.SECONDARY用于GNU Make的模式规则

我想使用GNU Make的特殊目标.SECONDARY来指定在创建为中间文件时不应删除特定模式规则的结果..PRECIOUS适用于模式,但奇怪的是,不是.SECONDARY.我不想使用.PRECIOUS,因为我确实希望在Make被信号中断的情况下删除文件,或者当与.DELETE_ON_ERROR结合使用时命令返回非零退出状态.有什么建议?

makefile gnu-make

9
推荐指数
1
解决办法
2465
查看次数

如何在makefile中获取名称列表的笛卡尔积(组合扩展)

使用GNU-make,假设我的Makefile中有两个列表,并且我想将它们组合起来以将其笛卡尔积作为另一个列表,以便我可以将其用作目标列表.

作为一个我不太清楚的语言的例子,R有一个函数expand.grid()可以实现这个目的.

我实际上想出了一种使用Makefile执行此操作的方法:

.PHONY: all

prefix := 1 2

base := A B 

add_prefix = $(addsuffix $(base), $(prefix))

Obj = $(foreach base, $(base), $(add_prefix))

all: 
    @echo $(Obj)
Run Code Online (Sandbox Code Playgroud)

但是,这非常hacky并且不以直观的方式使用addsuffix功能.有没有更好的方法呢?

makefile cartesian-product gnu-make

9
推荐指数
1
解决办法
643
查看次数

在makefile中删除文件之前检查文件是否存在

我在C++项目中有一个makefile(编译器:C++ 11).在使用makefile命令删除特定文件之前,如何检查特定文件是否存在?
这是代码:

bin: charstack.h error.h
        g++ -Wall -std=c++11 main.cpp charstack.cpp error.cpp -o bin

run:
        ./bin.exe

clean:
        rm bin.exe

# This statement removes auto generated backups on my system.
cl:
        rm charstack.h~ charstack.cpp~ main.cpp~ makefile~ error.h~ error.cpp~
Run Code Online (Sandbox Code Playgroud)

如何在用户通过之前检查自动生成的.~backup文件是否存在,然后再尝试删除它们

make cl
Run Code Online (Sandbox Code Playgroud)

在命令行?这里的目标是避免在运行"make cl"时将这些错误输出到终端:

rm: cannot remove `charstack.h~': No such file or directory
rm: cannot remove `charstack.cpp~': No such file or directory
rm: cannot remove `main.cpp~': No such file or directory
rm: cannot remove `error.h~': No such file or directory
rm: cannot …
Run Code Online (Sandbox Code Playgroud)

makefile gnu-make

9
推荐指数
1
解决办法
7098
查看次数

存储缓存的位置在哪里?

Make似乎将文件修改时间与某种修改时间的内部缓存进行比较.有谁知道这个缓存位于何处或如何访问它?

makefile gnu-make

9
推荐指数
2
解决办法
4315
查看次数

automake subdir-objects已禁用

我在使用automake时遇到了以下错误.我知道你可以把AUTOMAKE_OPTIONS = subdir-objects"放在Makefile.am的顶部.但是如何为所有文件设置这种行为,所以我不需要逐个进行呢?

Makefile.am:454: warning: source file 'libs/esl/src/esl_threadmutex.c' is in a subdirectory,
          Makefile.am:454: but option 'subdir-objects' is disabled
          Makefile.am:454: warning: source file 'libs/esl/ivrd.c' is in a subdirectory,
          Makefile.am:454: but option 'subdir-objects' is disabled
          Makefile.am:454: warning: source file 'libs/esl/src/esl_json.c' is in a subdirectory,
          Makefile.am:454: but option 'subdir-objects' is disabled
          Makefile.am:454: warning: source file 'libs/esl/src/esl_buffer.c' is in a subdirectory,
          Makefile.am:454: but option 'subdir-objects' is disabled
          tests/unit/unit.mk:6: warning: source file 'tests/unit/switch_event.c' is in a subdirectory,
          tests/unit/unit.mk:6: but option 'subdir-objects' is disabled
          Makefile.am:854:   'tests/unit/unit.mk' …
Run Code Online (Sandbox Code Playgroud)

linux automake gnu-make

9
推荐指数
1
解决办法
8516
查看次数