- 主题:这算是make的bug吗?
需求: 把一个包含相对路径和绝对路径的头文件目录列表, 统一变成绝对路径, 并加"-I"前缀
Makefile如下
```
IN := rel_dir1 rel_dir2 /abs_dir1
OUT := $(patsubst %, -I$(abspath %), $(IN))
show:
@echo $(OUT)
```
在/home/user/make_test目录下执行这个Makefile, 得到的输出是:
-I/home/user/make_test/rel_dir1 -I/home/user/make_test/rel_dir2 -I/home/user/make_test//abs_dir1
可见最后一个绝对路径处理错了
吊诡的是单独用$(abspath /abs_dir1)是没问题的
是make的bug吗?
--
FROM 124.71.93.*
不是make的bug。
在你的Makefile里,$(abspath %)会把相对路径转为绝对路径,但对已经是绝对路径的目录,比如/abs_dir1,它也当成当前工作目录的相对路径来处理,从而得到/home/user/make_test//abs_dir1这样的输出。
解决方法是在处理过程中检查路径是否已经是绝对路径。已经是绝对路径就不转了 ---- 在make中检查一个路径是相对的还是绝对的很容易,看看打头的字符是不是 / 就齐了。
下面是个更新后的Makefile:
IN := rel_dir1 rel_dir2 /abs_dir1
OUT := $(foreach d,$(IN),$(if $(filter /%,$d),-I$d,-I$(abspath $d)))
show:
@echo $(OUT)
↑↑注意 @echo前的缩进必须是 tab !! make 是不认空格的,但帖子只能是空格。
这里用$(foreach ...)来遍历IN变量中的每个目录,并且对每个目录用$(if $(filter /%,$d),...)来检查它是相对路径还是绝对路径。
如果它以/开头(即绝对路径),就直接加-I前缀;
如果不是,我们就使用$(abspath ...)将其转换为绝对路径,并添加-I前缀。
当你在/home/user/make_test目录下执行这个修改过的Makefile时,得到的输出应当是:
-I/home/user/make_test/rel_dir1 -I/home/user/make_test/rel_dir2 -I/abs_dir1
大概是这个意思吧,有问题你自己再调调
--
FROM 123.125.204.*
谢谢认真回复!
但单独执行$(abspath /abs_dir1)并不会出错,得到的依然是/abs_dir1
这不是不一致吗?
事实上我最后的解决也没有解决区分相对路径和绝对路径,而是换成了
OUT := $(foreach dir, $(IN), -I$(abspath $(dir)))
就没问题了
很难用什么设计思路去解释这种不一致性
【 在 tsa300 的大作中提到: 】
: 不是make的bug。
: 在你的Makefile里,$(abspath %)会把相对路径转为绝对路径,但对已经是绝对路径的目录,比如/abs_dir1,它也当成当前工作目录的相对路径来处理,从而得到/home/user/make_test//abs_dir1这样的输出。
: 解决方法是在处理过程中检查路径是否已经是绝对路径。已经是绝对路径就不转了 ---- 在make中检查一个路径是相对的还是绝对的很容易,看看打头的字符是不是 / 就齐了。
: ...................
--
修改:Machael FROM 124.71.93.*
FROM 124.70.231.*
你可以用 foreach 试试,看看这样逐个 abspath 出来的是不是全对
IN := rel_dir1 rel_dir2 /abs_dir1
OUT := $(foreach dir,$(IN),$(eval ABS_DIR := $(abspath $(dir))) -I$(ABS_DIR))
show:
@echo $(OUT)
↑↑ tab
【 在 Machael 的大作中提到: 】
: 谢谢,
: 但单独执行$(abspath /abs_dir1)并不会出错,得到的依然是/abs_dir1
: 这不是不一致吗?
: ...................
--
FROM 123.125.204.*
事实上我把这个问题抛给chatgpt,
它也认为我原来的写法没问题,
也就是它也认为patsubst+abspath会自动识别处理相对路径和绝对路径
【 在 tsa300 的大作中提到: 】
: 不是make的bug。
: 在你的Makefile里,$(abspath %)会把相对路径转为绝对路径,但对已经是绝对路径的目录,比如/abs_dir1,它也当成当前工作目录的相对路径来处理,从而得到/home/user/make_test//abs_dir1这样的输出。
: 解决方法是在处理过程中检查路径是否已经是绝对路径。已经是绝对路径就不转了 ---- 在make中检查一个路径是相对的还是绝对的很容易,看看打头的字符是不是 / 就齐了。
: ...................
--
FROM 124.70.231.*
你这是粘贴的来自AI的回答吗?
【 在 tsa300 的大作中提到: 】
: 你可以用 foreach 试试,看看这样逐个 abspath 出来的是不是全对
: IN := rel_dir1 rel_dir2 /abs_dir1
: OUT := $(foreach dir,$(IN),$(eval ABS_DIR := $(abspath $(dir))) -I$(ABS_DIR))
: ...................
--
FROM 220.196.192.*