Makefile:从 $^

问题描述 投票:0回答:1

我正在用 Lex 和 Yacc 制作一个编译器。要编译我的

main
,我需要先运行 yacc,以便文件
y.tab.h
存在。但是,我不希望在编译所述
$^
时将该文件包含在
main
变量中,因为编译器不喜欢获取
.h
文件作为输入。

有没有办法让该规则/配方依赖于

y.tab.h
,但将其排除在
$^
之外?

如果不是,(意思是,如果这个问题是 XY 问题),是否有更好的方法来构建此 Makefile 来实现该目标?

这是我的 makefile :

targets := ccpy

################################### Options ####################################

cc            := gcc
cFlags        := -c -O3
cFlagsLenient := $(cFlags) -w
cFlagsHard    := $(cFlags) -Wall -pedantic
cFlagsDebug   := -c -W -Wall -pedantic -g -Og
ldFlags       := -lm -ly -ll
ldFlagsDebug  := -g $(ldFlags)

################################### Folders ####################################

binDir   := ./bin
debugDir := ./debug
objDir   := ./obj
srcDir   := ./src
testDir  := ./test

################################ File categories ###############################

mains    := $(targets:%=$(objDir)/%.o)

srcL     := $(wildcard $(srcDir)/*.l)
srcY     := $(wildcard $(srcDir)/*.y)

outL     := $(srcL:$(srcDir)/%.l=$(srcDir)/%.c)
outY     := $(srcY:$(srcDir)/%.y=$(srcDir)/%.c)

objL     := $(outL:$(srcDir)/%.c=$(objDir)/%.o)
objY     := $(outY:$(srcDir)/%.c=$(objDir)/%.o)
cleanY   := $(outY) $(srcY:$(srcDir)/%.y=$(srcDir)/%.h) $(srcDir)/y.output $(srcdir)/y.gv

srcC     := $(filter-out $(outL) $(outY), $(wildcard $(srcDir)/*.c))
objC     := $(srcC:$(srcDir)/%.c=$(objDir)/%.o)

obj      := $(objC) $(objL) $(objY)
objDebug := $(obj:$(objDir)/%.o=$(debugDir)/%.do)

srcTest  := $(wildcard $(testDir)/*.c)
tests    := $(srcTest:$(testDir)/%.c=$(binDir)/%)

#################################### Recipes ###################################

# Basic
all  : $(targets)
again : clean all
debug: $(targets:%=%.db)
test : $(tests)
objects: $(obj)

# Check Variables
info: 
    $(info mains    : $(mains))
    $(info srcC     : $(srcC))
    $(info objC     : $(objC))
    $(info srcL     : $(srcL))
    $(info outL     : $(outL))
    $(info objL     : $(objL))
    $(info srcY     : $(srcY))
    $(info outY     : $(outY))
    $(info objY     : $(objY))
    $(info obj      : $(obj))
    $(info objDebug : $(objDebug))
    $(info srcTest  : $(srcTest))
    $(info tests    : $(tests))

# Final Executables
$(targets): % : $(objDir)/%.o $(obj)
    $(cc) -o $@ $^ $(ldFlags)

# Objects directly compiled from C
$(objC): $(objDir)/%.o : $(srcDir)/%.c
    $(cc) $(cFlagsHard) $^ -o $@

# Objects made by Lex and Yacc
$(objL) $(objY): $(objDir)/%.o : $(srcDir)/%.c
    $(cc) $(cFlagsLenient) $^ -o $@

# Files made by Lex
$(outL): $(srcDir)/%.c : $(srcDir)/%.l $(outY)
    lex -o $@ $<

# Files made by Yacc
$(outY): $(srcDir)/%.c : $(srcDir)/%.y
    yacc -v -d -Wcounterexamples --file-prefix="$(srcDir)/y" $^

# Debug executables (outdated)
$(targets:%=%.db): $(objDebug)
    $(cc) -o $@ $^ $(ldFlagsDebug)

# Debug objects (outdated)
$(objDebug): $(debugDir)/%.do : $(srcDir)/%.c
    $(cc) $(cFlagsDebug) $^ -o $@

# Automated testing
$(tests): $(binDir)/%_test : $(testDir)/%_test.c $(filter-out $(mains), $(obj))
    $(cc) -o $@ $^ $(ldFlags) 
    $@

clean: 
    rm -rf $(objDir)/*.o $(debugDir)/*.do $(targets) $(tests) $(cleanY) $(outL)

c makefile yacc lex
1个回答
0
投票

$^
更改为
$(filter-out %.h, $^)
filter-out
函数删除与模式匹配的所有单词(非空白字符序列)。

© www.soinside.com 2019 - 2024. All rights reserved.