【问题标题】:inconsistent behaviour grouped target in Make/Makefile with/without dependencies具有/不具有依赖关系的 Make/Makefile 中的不一致行为分组目标
【发布时间】:2022-06-15 23:46:28
【问题描述】:

情况: 正在从 Internet 将文件 f1db_csv.zip 下载到 data/raw 中,接下来将解压缩 zip 文件,并将 15 个 .csv 文件提取到 data/raw 中。

每当我运行以下代码时,一切正常,如果 data/raw 中的一个或多个 .csv 文件被触摸/删除,它们将从 data/raw/f1db_csv.zip 中提取,一切正常,除了wget 命令也被调用。

print-% :
    @echo "$*=$($*)"

RAW = data/raw
PROCESS = data/process
RAW_NAMES = circuits constructor_results constructor_standings constructors driver_standings\
drivers lap_times pit_stops qualifying races results seasons sprint_results status
RAW_FILES = $(addsuffix .csv, $(addprefix $(RAW)/,$(RAW_NAMES)))

$(RAW_FILES) : 
    wget -nc --no-check-certificate -P $(RAW) http://ergast.com/downloads/f1db_csv.zip
    unzip -o -d $(RAW) -j $(RAW)/f1db_csv.zip "$(@F)" #this line extracts only the specified file from the .zip-file

data/process/roundtimes.csv : code/create_roundtimes.R $(RAW_FILES)
    R -e "source('code/create_roundtimes.R')"

假设我删除了三个文件(constructor_results.csv、constructor_standings.csv 和 constructors.csv),那么“make data/process/roundtimes.csv”的输出是:

wget -nc --no-check-certificate -P data/raw http://ergast.com/downloads/f1db_csv.zip
File ‘data/raw/f1db_csv.zip’ already there; not retrieving.

unzip -o -d data/raw -j data/raw/f1db_csv.zip "constructor_results.csv" 
Archive:  data/raw/f1db_csv.zip
  inflating: data/raw/constructor_results.csv  
wget -nc --no-check-certificate -P data/raw http://ergast.com/downloads/f1db_csv.zip
File ‘data/raw/f1db_csv.zip’ already there; not retrieving.

unzip -o -d data/raw -j data/raw/f1db_csv.zip "constructor_standings.csv"
Archive:  data/raw/f1db_csv.zip
  inflating: data/raw/constructor_standings.csv  
wget -nc --no-check-certificate -P data/raw http://ergast.com/downloads/f1db_csv.zip
File ‘data/raw/f1db_csv.zip’ already there; not retrieving.

unzip -o -d data/raw -j data/raw/f1db_csv.zip "constructors.csv"
Archive:  data/raw/f1db_csv.zip
  inflating: data/raw/constructors.csv  

为了将 wget 命令与 zip 命令拆分,我尝试拆分以下代码:

$(RAW_FILES) : 
    wget -nc --no-check-certificate -P $(RAW) http://ergast.com/downloads/f1db_csv.zip
    unzip -o -d $(RAW) -j $(RAW)/f1db_csv.zip "$(@F)"

进入:

$(RAW)/f1db_csv.zip :
    wget -nc --no-check-certificate -P $(RAW) http://ergast.com/downloads/f1db_csv.zip

$(RAW_FILES) : $(RAW)/f1db_csv.zip
    unzip -o -d $(RAW) -j $(RAW)/f1db_csv.zip "$@"

这会导致针对 $(RAW_FILES) 的每个成员运行该命令。

我尝试更新到 4.3 以便使用:

$(RAW)/f1db_csv.zip :
    wget -nc --no-check-certificate -P $(RAW) http://ergast.com/downloads/f1db_csv.zip

$(RAW_FILES) &: $(RAW)/f1db_csv.zip
    unzip -o -d $(RAW) -j $(RAW)/f1db_csv.zip "$@"

但这会导致只对第一个成员运行命令:

unzip -o -d data/raw -j data/raw/f1db_csv.zip data/raw/circuits.csv

如何解决这个问题?

【问题讨论】:

  • 澄清一下:``` $(RAW_FILES) : unzip -o -d $(RAW) -j $(RAW)/f1db_csv.zip "$(@F)" ``` 确实我需要什么,但是一旦我添加 $(RAW)/f1db_csv.zip 作为依赖项,行为就会完全改变。

标签: bash makefile


【解决方案1】:

您使用分组目标的最后一个选项是正确的,但您不能使用 $@,因为它只会扩展到 make 尝试构建的特定文件。

如果你想将所有目标传递给命令,你应该只使用$(RAWFILES):

$(RAW)/f1db_csv.zip :
        wget -nc --no-check-certificate -P $(@D) http://ergast.com/downloads/$(@F)

$(RAW_FILES) &: $(RAW)/f1db_csv.zip
        unzip -o -d $(<D) -j $< $(RAWFILES)

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 2017-06-13
    • 2012-02-08
    • 2015-12-20
    • 2015-02-13
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多