如何使目标依赖于LIB文件,但是从$ ^排除(VPATH参与)? [英] How to make the target depend on lib file, but exclude it from $^ (VPATH involved)?

查看:153
本文介绍了如何使目标依赖于LIB文件,但是从$ ^排除(VPATH参与)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下这样的结构:

 根/
|
+ - 包括/
+ - SRC /
+ - 编译/
+ - 的lib /
+ - 测试/
    |
    + - 通用
    + - TEST1
    + - TEST2
    + - TEST3

测试/ 文件夹普通/ 包含一对夫妇的生成数据或读取数据源文件记录的文件等,这是所有测试之间共享。因此,每个测试只有一个文件; 的main.c (目前)。在的Makefile 每个测试的是这样的:

  .SUFFIXES:
.SUFFIXES:.C的.oTARGET:=测试
#操作系统有关的东西不再赘述
CFLAGS + = -I ../../包括-I ../常见
LDFLAGS + = -L ../../ lib中-lnameVPATH = ../common.PHONY:都是干净的
所有:$(TARGET)
清洁:
     - $(RM)* $的.o(TARGET)
为简便起见去掉#其他目标对象:= main.o中io.o read_str.o
$(TARGET):$(对象)../../lib/libname.a
    $(LD)-o $ @ $(对象)$(LDFLAGS)
%的.o:%.C
    $(CC)-c $(CFLAGS)-o $ @ $<
main.o中:main.c中io.h $(通配符../../include/*.h)

起初,我在每次测试复制普通/ 文件,一切都很好,但现在我把它们放在普通/ 和使用 VPATH ,我面对的一个问题。

让我解释一下几行:

  main.o中:main.c中io.h $(通配符../../include/*.h)
               ^^^^
           VPATH正确认定共同文件/$(TARGET):$(对象)../../lib/libname.a
                      ^^^^^^^^^^^^^^^^^^^
                  如果磁带库重建,该项测试需要重新连接    $(LD)-o $ @ $(对象)$(LDFLAGS)
                ^^^^^^^^^^
            我不能用$ ^,因为这还包括../../lib/libname.a

正如你可能已经猜到了,因为普通/ *。Ø文件不在此文件夹中, $(LD)无法找到他们。在另一方面,制作,因为 VPATH = ../共同没有问题找到他们。如果我可以删除 ../../的lib / libName.a的,然后用 $ ^ ,我可以给正确的路径到目标文件。

删除依赖性但是库文件,意味着当我制作在顶层,这些测试将不会被更新,如果仅LIB本身正在更新

所以,我的问题是,我怎么能告诉制作还有另一个文件的依赖(一个lib文件),但它不是在命令中使用在它下面,考虑到其他依赖使用发现 VPATH

我想有关删除依赖关系,并在的Makefile 即建立 libName.a的,后添​​加一个命令该库是由它告诉的Makefile 取值测试,以消除他们的目标取值:

 的lib / Makefile文件:.SUFFIXES:TARGET = libName.a的
VPATH = ../build.PHONY:都是干净的
所有:$(TARGET)
清洁:
         - $(RM)$(TARGET)$(TARGET):list.o of.o my.o library.o files.o
        $(AR)$(TARGET)$ ^
        @ $(MAKE)--no打印目录-C ../tests remove_targets

这将迫使 $(LD)再次使他们。然而,这种解决方案往往使的Makefile 的关系发展成一个烂摊子。在的Makefile 是构建LIB无关是否有考试或没有,我preFER,让他们去耦。


我建造并测试了很多,这就是为什么我试图让依赖完整,使制作取最小值可能采取的行动,以建立正确的一切。上面写着,清洁和重建每次一个解决方案是不是一个选项。

我也知道这种语法,如果​​我想给的lib文件目录 GCC 可能被使用,而不是使用 -Lpath /到/ lib目录-lname 。我不但是知道这是一个好主意(我的意思是,我总是看到了 -L 链接,我不知道是否有一个缺点时,直接给库文件)

顺便说一句,如果我做一些可怕的错误,如果我正在为自己太困难,请告诉我应该怎么做正确。


解决方案

  

所以,我的问题是,我怎么能告诉make还有另一个文件(LIB文件)的依赖,但它不是在它下面的命令中使用,因为其他的依赖正在使用VPATH发现了什么?


现在的问题是我怎样才能使一个LIB prerequisite,但并不适用于所有prerequisites名单?

这可能不是最好的答案,但应该工作,只是过滤出来列表

  $(TARGET):$(对象)../../lib/libname.a
    $(LD)-o $ @ $(过滤出../../lib/libname.a,$^)$(LDFLAGS)

Imagine this structure:

root/
|
+-- include/
+-- src/
+-- build/
+-- lib/
+-- tests/
    |
    +-- common
    +-- test1
    +-- test2
    +-- test3

In tests/, the folder common/ contains a couple of source files that generate data or read data from logged file etc, which are shared between all tests. Each test therefore has only one file; main.c (currently). The Makefile of each test looks like this:

.SUFFIXES:
.SUFFIXES: .c .o

TARGET := test
# OS dependent stuff omitted for brevity
CFLAGS += -I../../include -I../common
LDFLAGS += -L../../lib -lname

VPATH = ../common

.phony: all clean
all: $(TARGET)
clean:
    -$(RM) *.o $(TARGET)
# Other targets removed for brevity

OBJECTS := main.o io.o read_str.o
$(TARGET): $(OBJECTS) ../../lib/libname.a
    $(LD) -o $@ $(OBJECTS) $(LDFLAGS)
%.o: %.c
    $(CC) -c $(CFLAGS) -o $@ $<
main.o: main.c io.h $(wildcard ../../include/*.h)

At first I had the common/ files copied in each test and everything was fine, but now that I put them in common/ and used VPATH, I am facing an issue.

Let me explain a few lines:

main.o: main.c io.h $(wildcard ../../include/*.h)
               ^^^^
           VPATH correctly finds this file in common/

$(TARGET): $(OBJECTS) ../../lib/libname.a
                      ^^^^^^^^^^^^^^^^^^^
                  If the library is rebuilt, the tests need to re-link

    $(LD) -o $@ $(OBJECTS) $(LDFLAGS)
                ^^^^^^^^^^
            I can't use $^ because that also includes ../../lib/libname.a

As you may have already guessed, since the common/*.o files are not in this folder, $(LD) fails to find them. On the other hand, make, given VPATH = ../common has no problem finding them. If I could remove ../../lib/libname.a, then with $^, I could give the correct paths to the object files.

Removing the dependency to the lib file however, means that when I make at the top-level, the tests will not get updated if only the lib itself is being updated.

So, my question is, how can I tell make there is a dependency to another file (a lib file) but it is not used in the command below it, given that the other dependencies are found using VPATH?

I thought about removing the dependencies, and in the Makefile that builds libname.a, add a command after the library is made that tells the Makefiles of tests to remove their TARGETs:

lib/Makefile:

.SUFFIXES:

TARGET = libname.a
VPATH = ../build

.PHONY: all clean
all: $(TARGET)
clean:
        -$(RM) $(TARGET)

$(TARGET): list.o of.o my.o library.o files.o
        $(AR) $(TARGET) $^
        @$(MAKE) --no-print-directory -C ../tests remove_targets

This would force $(LD) to make them again. This solution however tends to make the Makefile relationships into a mess. The Makefile that builds the lib is unrelated to whether there are tests or not, and I prefer to keep them decoupled.


I build and test a lot, that is why I try to get the dependencies complete, so that make takes the minimum possible actions to correctly build everything. A solution that says, clean and rebuild every time is not an option.

I am also aware of this syntax, which could be used if I wanted to give the lib file directory to gcc, instead of using -Lpath/to/lib -lname. I am not sure however if that is a good idea (I mean, I always saw linking with -L, and I'm not sure if there is a disadvantage when directly giving the library file)

By the way, if I am doing something horribly wrong, or if I am making it too difficult for myself, please tell me how this should be done correctly.

解决方案

So, my question is, how can I tell make there is a dependency to another file (a lib file) but it is not used in the command below it, given that the other dependencies are found using VPATH?

The question is "how can I make LIB a prerequisite but not be in the list of all prerequisites?"

This may not be the best answer, but should work, just filter it out of the list:

$(TARGET): $(OBJECTS) ../../lib/libname.a
    $(LD) -o $@ $(filter-out ../../lib/libname.a,$^) $(LDFLAGS)

这篇关于如何使目标依赖于LIB文件,但是从$ ^排除(VPATH参与)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆