GNU 进行奇怪的变量替换

发布于 2025-01-07 00:55:19 字数 3812 浏览 0 评论 0原文

我有以下 Makefile:

CPPCOMPILER=g++
CCOMPILER=gcc
#CPPCOMPILER=i586-mingw32msvc-g++

FLAGS=-Wall -g -O3
LIBRARIES=-lpthread
MODULES=obj/HTTPRequest.o obj/main.o obj/Server.o obj/SocketUtils.o obj/HTTPServer.o \
    obj/CookieManager.o obj/FileLister.o
STATIC=obj/static/files.html.o obj/static/login.html.o

all: $(MODULES) $(STATIC)
    $(CPPCOMPILER) $(MODULES) $(STATIC) $(LIBRARIES) -o httpserver

obj/main.o : main.cpp
    @mkdir -p obj
    $(CPPCOMPILER) -c $(FLAGS) $< -o $@ 

obj/static/%.o : %
    @mkdir -p obj/static
    file2obj $< $(subst .,_,$<) > $<.c
    $(CCOMPILER) $<.c -o $@ -c $(FLAGS)   #<-------***THIS LINE***

obj/%.o : %.cpp %.h
    @mkdir -p obj
    $(CPPCOMPILER) -c $(FLAGS) $< -o $@ 

clean:
    rm -rf $(STATIC) $(MODULES) httpserver

我有 files.html,其中 file2obj 发出 C 源代码。此代码被编译为 .o 文件。

然而,make 过程与我的预期有些不同。输出如下:

thrustmaster@thrustmaster:~/Code/HTTPFileSharer$ make
cc     files.html.c   -o files.html #<--------- ****THIS LINE!****
[and more linker errors here because of wrong command]
make: *** [files.html] Error 1
  • 在这种情况下如何调用 cc?我期待gcc。 (我在另一个项目中也遇到了类似的问题,但结果并不严重。)
  • 为什么它会消耗掉一些参数呢?另外 -o 参数是错误的。(我得到 -o files.html
  • 有几次 files.html 被删除。关于其背后的原因有什么想法吗?

我正在使用 GNU make 3.81。

我的 Makefile 代码有什么问题吗?或者是 GNU/make 中的一些已知错误?

任何建议/指示/建议将不胜感激:-)

谢谢


更新

我在这里提出了另一个案例,我面临着类似的问题。

生成文件:

CPPCOMPILER=g++
CCOMPILER=gcc
FLAGS=-Wall -pg -O3
LIBRARIES=`pkg-config --libs libglfw` -lm -lGLU -lGL -lXrandr
UNITS=obj/main.o obj/TextureManager.o obj/Thread.o obj/Tile.o obj/PictureTile.o     obj/Coverflow.o obj/Vector3D.o \
        obj/TilePopulator.o obj/FileLister.o
SOIL_DEPENDS=soil/image_DXT.c  soil/image_helper.c  soil/SOIL.c  soil/stbi_DDS_aug_c.h      soil/stb_image_aug.c \
                soil/image_DXT.h  soil/image_helper.h  soil/SOIL.h  soil/stbi_DDS_aug.h      soil/stb_image_aug.h
SOIL_UNITS=obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o     soil/stb_image_aug.o

all: $(SOIL_UNITS) $(UNITS)
        $(CPPCOMPILER) $(FLAGS) $(SOIL_UNITS) $(UNITS) $(LIBRARIES) -o coverflow

obj/soil/%.o : soil/%.c
        @mkdir -p obj/soil
        $(CCOMPILER) -c $< -o $@     #<--Issue in this line 

obj/main.o : main.cpp
        @mkdir -p obj
        $(CPPCOMPILER) -c $(FLAGS) $< -o $@ 
obj/%.o : %.cpp %.h
        @mkdir -p obj
        $(CPPCOMPILER) -c $(FLAGS) $< -o $@ 
clean:
        rm -rf $(UNITS) $(SOIL_UNITS) coverflow

输出:

thrustmaster@thrustmaster:~/Code/Skroll$ make
gcc -c soil/image_DXT.c -o obj/soil/image_DXT.o
gcc -c soil/image_helper.c -o obj/soil/image_helper.o
gcc -c soil/SOIL.c -o obj/soil/SOIL.o
cc    -c -o soil/stb_image_aug.o soil/stb_image_aug.c  #<-----**THIS LINE**
g++ -c -Wall -pg -O3 main.cpp -o obj/main.o 
g++ -c -Wall -pg -O3 TextureManager.cpp -o obj/TextureManager.o 
g++ -c -Wall -pg -O3 Thread.cpp -o obj/Thread.o 
g++ -c -Wall -pg -O3 Tile.cpp -o obj/Tile.o 
g++ -c -Wall -pg -O3 PictureTile.cpp -o obj/PictureTile.o 
g++ -c -Wall -pg -O3 Coverflow.cpp -o obj/Coverflow.o 
g++ -c -Wall -pg -O3 Vector3D.cpp -o obj/Vector3D.o 
g++ -c -Wall -pg -O3 TilePopulator.cpp -o obj/TilePopulator.o 
g++ -c -Wall -pg -O3 FileLister.cpp -o obj/FileLister.o 
g++ -Wall -pg -O3 obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o     soil/stb_image_aug.o obj/main.o obj/TextureManager.o obj/Thread.o obj/Tile.o     obj/PictureTile.o obj/Coverflow.o obj/Vector3D.o obj/TilePopulator.o obj/FileLister.o `pkg-    config --libs libglfw` -lm -lGLU -lGL -lXrandr -o coverflow

I have the following Makefile:

CPPCOMPILER=g++
CCOMPILER=gcc
#CPPCOMPILER=i586-mingw32msvc-g++

FLAGS=-Wall -g -O3
LIBRARIES=-lpthread
MODULES=obj/HTTPRequest.o obj/main.o obj/Server.o obj/SocketUtils.o obj/HTTPServer.o \
    obj/CookieManager.o obj/FileLister.o
STATIC=obj/static/files.html.o obj/static/login.html.o

all: $(MODULES) $(STATIC)
    $(CPPCOMPILER) $(MODULES) $(STATIC) $(LIBRARIES) -o httpserver

obj/main.o : main.cpp
    @mkdir -p obj
    $(CPPCOMPILER) -c $(FLAGS) 
lt; -o $@ 

obj/static/%.o : %
    @mkdir -p obj/static
    file2obj 
lt; $(subst .,_,
lt;) > 
lt;.c
    $(CCOMPILER) 
lt;.c -o $@ -c $(FLAGS)   #<-------***THIS LINE***

obj/%.o : %.cpp %.h
    @mkdir -p obj
    $(CPPCOMPILER) -c $(FLAGS) 
lt; -o $@ 

clean:
    rm -rf $(STATIC) $(MODULES) httpserver

I have files.html for which file2obj emits C source code. This code gets compiled to .o file.

However the make process is somewhat different that what I expected. Here's the output:

thrustmaster@thrustmaster:~/Code/HTTPFileSharer$ make
cc     files.html.c   -o files.html #<--------- ****THIS LINE!****
[and more linker errors here because of wrong command]
make: *** [files.html] Error 1
  • How can cc get invoked in this case? I expect gcc. (I faced similar issues in another project too, but the results weren't serious.)
  • And how come it eats up some of the parameters? Also -o parameter is wrong.(I get -o files.html)
  • A few times files.html got deleted. Any ideas as to what can be the reason behind it?

I am using GNU make 3.81.

Is there anything wrong with my Makefile code? Or is it some known bug in GNU/make?

Any advice/pointers/suggestiosn will be greatly appreciated :-)

Thanks


UPDATE

I am putting here another case, where I am facing a similar problem.

Makefile:

CPPCOMPILER=g++
CCOMPILER=gcc
FLAGS=-Wall -pg -O3
LIBRARIES=`pkg-config --libs libglfw` -lm -lGLU -lGL -lXrandr
UNITS=obj/main.o obj/TextureManager.o obj/Thread.o obj/Tile.o obj/PictureTile.o     obj/Coverflow.o obj/Vector3D.o \
        obj/TilePopulator.o obj/FileLister.o
SOIL_DEPENDS=soil/image_DXT.c  soil/image_helper.c  soil/SOIL.c  soil/stbi_DDS_aug_c.h      soil/stb_image_aug.c \
                soil/image_DXT.h  soil/image_helper.h  soil/SOIL.h  soil/stbi_DDS_aug.h      soil/stb_image_aug.h
SOIL_UNITS=obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o     soil/stb_image_aug.o

all: $(SOIL_UNITS) $(UNITS)
        $(CPPCOMPILER) $(FLAGS) $(SOIL_UNITS) $(UNITS) $(LIBRARIES) -o coverflow

obj/soil/%.o : soil/%.c
        @mkdir -p obj/soil
        $(CCOMPILER) -c 
lt; -o $@     #<--Issue in this line 

obj/main.o : main.cpp
        @mkdir -p obj
        $(CPPCOMPILER) -c $(FLAGS) 
lt; -o $@ 
obj/%.o : %.cpp %.h
        @mkdir -p obj
        $(CPPCOMPILER) -c $(FLAGS) 
lt; -o $@ 
clean:
        rm -rf $(UNITS) $(SOIL_UNITS) coverflow

OUTPUT:

thrustmaster@thrustmaster:~/Code/Skroll$ make
gcc -c soil/image_DXT.c -o obj/soil/image_DXT.o
gcc -c soil/image_helper.c -o obj/soil/image_helper.o
gcc -c soil/SOIL.c -o obj/soil/SOIL.o
cc    -c -o soil/stb_image_aug.o soil/stb_image_aug.c  #<-----**THIS LINE**
g++ -c -Wall -pg -O3 main.cpp -o obj/main.o 
g++ -c -Wall -pg -O3 TextureManager.cpp -o obj/TextureManager.o 
g++ -c -Wall -pg -O3 Thread.cpp -o obj/Thread.o 
g++ -c -Wall -pg -O3 Tile.cpp -o obj/Tile.o 
g++ -c -Wall -pg -O3 PictureTile.cpp -o obj/PictureTile.o 
g++ -c -Wall -pg -O3 Coverflow.cpp -o obj/Coverflow.o 
g++ -c -Wall -pg -O3 Vector3D.cpp -o obj/Vector3D.o 
g++ -c -Wall -pg -O3 TilePopulator.cpp -o obj/TilePopulator.o 
g++ -c -Wall -pg -O3 FileLister.cpp -o obj/FileLister.o 
g++ -Wall -pg -O3 obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o     soil/stb_image_aug.o obj/main.o obj/TextureManager.o obj/Thread.o obj/Tile.o     obj/PictureTile.o obj/Coverflow.o obj/Vector3D.o obj/TilePopulator.o obj/FileLister.o `pkg-    config --libs libglfw` -lm -lGLU -lGL -lXrandr -o coverflow

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

_蜘蛛 2025-01-14 00:55:19

GNU Make 有一个内置的隐式规则,用于从 Xc 构建文件 X:

%: %.c
#  commands to execute (built-in):
    $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@

当您运行“make”时,似乎会调用此隐式规则。

虽然这不是一个好的永久解决方案,但您可以通过使用 -r (或 --no-builtin-rules)选项运行 make 来禁用此问题,从而避免此问题。隐含规则。

GNU Make has a built-in implicit rule for building a file, X, from X.c:

%: %.c
#  commands to execute (built-in):
    $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@

It appears this implicit rule is being invoked when you run "make".

While not a good permanent solution, you may be able to avoid this problem by running make with the -r (or --no-builtin-rules) option to disable the implicit rules.

表情可笑 2025-01-14 00:55:19

在第一种情况下,您尝试使用此规则构建 obj/static/files.html.o:

obj/static/%.o : %
    @mkdir -p obj/static
    file2obj 
lt; $(subst .,_,
lt;) > 
lt;.c
    $(CCOMPILER) 
lt;.c -o $@ -c $(FLAGS)

在 Make 运行此规则之前,它将首先检查先决条件(files .html)可以/应该重建。有一条隐式规则将从 files.html.c 构建 files.html,因此如果 files.html.c< 将会发生这种情况/code> 存在。 (你似乎与 Make 期望的方向相反;我对构建 HTML 的了解不够,不知道这是否是一个好主意。)如果可行,Make 将考虑 files.html 一个中间文件,并且会在出现时删除它不再需要。

解决这个问题的方法不止一种。最简单的可能是编写自己的构建 files.html 规则,该规则会否决 Make 的规则并且不执行任何操作:

%.html: %.html.c;

在第二种情况下,您在 SOIL_UNITS 变量中犯了一个小错误:

SOIL_UNITS=obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o soil/stb_image_aug.o

注意最后一个术语。您有一个针对 obj/soil/%.o 的规则,但没有针对 soil/%.o 的规则,因此 Make 会依赖其隐式规则。只需将该术语更改为 obj/soil/stb_image_aug.o 即可。

In the first case, you are trying to build obj/static/files.html.o using this rule:

obj/static/%.o : %
    @mkdir -p obj/static
    file2obj 
lt; $(subst .,_,
lt;) > 
lt;.c
    $(CCOMPILER) 
lt;.c -o $@ -c $(FLAGS)

Before Make runs this rule, it will first check to see if the prerequisite (files.html) can/should be rebuilt. There is an implicit rule that will build files.html from files.html.c, so that's what will happen if files.html.c exists. (You seem to be going in the opposite direction from what Make expects; I don't know enough about building HTML to know if that's a good idea.) And if that works, Make will consider files.html an intermediate file, and will delete it when it is no longer needed.

There's more than one way to solve this problem. The simplest is probably to write your own rule for building files.html, which overrules Make's rule and does nothing:

%.html: %.html.c;

In the second case you made a small mistake in your SOIL_UNITS variable:

SOIL_UNITS=obj/soil/image_DXT.o obj/soil/image_helper.o obj/soil/SOIL.o soil/stb_image_aug.o

Notice the last term. You have a rule for obj/soil/%.o, but not for soil/%.o, so Make falls back on its implicit rule. Just change that term to obj/soil/stb_image_aug.o.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文