linux - GNU 进行奇怪的变量替换

标签 linux makefile

我有以下 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.htmlfile2obj 为其生成 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

最佳答案

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

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

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

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

关于linux - GNU 进行奇怪的变量替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9349927/

相关文章:

php - 如何通过 proc_open 后台进程并访问 STDIN?

linux - chroot jail + ssh key 被拒绝

c++ - 为我的程序使用 make

c++ - 函数的多重定义,为什么守卫没有捕获这个?

macos - 在 Mac OSX 上安装 flite 时出错

c - 在 C 中使用 fts_children() 的意外结果

Linux - 断开连接发送超时

linux 粘贴和剪切

linux - 使内核模块 makefile 识别源的绝对路径?

c - Windows 中的生成文件