GNU 进行奇怪的变量替换
我有以下 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 expectgcc
. (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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
GNU Make 有一个内置的隐式规则,用于从 Xc 构建文件 X:
当您运行“make”时,似乎会调用此隐式规则。
虽然这不是一个好的永久解决方案,但您可以通过使用
-r
(或--no-builtin-rules
)选项运行 make 来禁用此问题,从而避免此问题。隐含规则。GNU Make has a built-in implicit rule for building a file, X, from X.c:
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.在第一种情况下,您尝试使用此规则构建 obj/static/files.html.o:
在 Make 运行此规则之前,它将首先检查先决条件(
files .html
)可以/应该重建。有一条隐式规则将从files.html.c
构建files.html
,因此如果files.html.c< 将会发生这种情况/code> 存在。 (你似乎与 Make 期望的方向相反;我对构建 HTML 的了解不够,不知道这是否是一个好主意。)如果可行,Make 将考虑
files.html
一个中间文件,并且会在出现时删除它不再需要。解决这个问题的方法不止一种。最简单的可能是编写自己的构建
files.html
规则,该规则会否决 Make 的规则并且不执行任何操作:在第二种情况下,您在
SOIL_UNITS
变量中犯了一个小错误:注意最后一个术语。您有一个针对 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: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 buildfiles.html
fromfiles.html.c
, so that's what will happen iffiles.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 considerfiles.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:In the second case you made a small mistake in your
SOIL_UNITS
variable:Notice the last term. You have a rule for
obj/soil/%.o
, but not forsoil/%.o
, so Make falls back on its implicit rule. Just change that term toobj/soil/stb_image_aug.o
.