关于makefile模式规则中指定obj目录 -- 在线等待

时间:2022-10-02 12:51:56
我的目录结构如下:
工作组目录
     bims
    +- src
    +- obj

我的当前目录是src, 源码以及.h文件均在src中, 然后我想通过模式规则将src目录下的所有.cpp编译出的中间文件存放到obj中. 请问模式规则应如何编写?
下面是我的makefile文件的内容:

SRCPATH =
OBJPATH = ..\objs

OBJS = $(OBJPATH)\bims_core.obj
LIBS = user32.lib gdi32.lib
TARGET = ..\bims.exe

CXXFLAGS = /c /D "_UNICODE" /D "UNICODE" /Fo"../objs/"
CXX = cl.exe

LINK = link.exe
LINKFLAGS = /out:$(TARGET)

# 连接可执行文件.
$(TARGET):$(OBJS)
$(LINK) $(LINKFLAGS) $(LIBS) $(OBJS)

问题就在这里. 我这样指定之后, 总是提示: No rule to make target `..\objs\bims_core.obj', needed by `..\bims.exe'.信息.
$(OBJPATH)\%.obj:%.cpp
$(CXX) $(CXXFLAGS) $<

%.obj:%.cpp
$(CXX) $(CXXFLAGS) $<

all: $(TARGET)

clean:
rm -f $(OBJS) $(TARGET)

14 个解决方案

#1


少建一个 gcc-build 目录 
mkdir /mnt/lfs/sources/gcc-build

#2


不是吧, 我是在windows平台上用的make, 并且我只是想让模式规则自动推导成:

..\objs\bims.obj:bims.cpp

bims.cpp就是当前目录下的文件. 问题是我如何能用模式规则实现上面的一般推导规则.

#3


试试看将下面这段改掉:
-------------------
$(OBJPATH)\%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < 

%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < 
-------------------
改成:
-------------------
.cpp.o:
$(CXX) $(CXXFLAGS) $<
mv $< $(OBJPATH)
-------------------

#4


噢, 对不起, 我用的是GNU Make 3.81版本, 是从MingW中获得的. 你的这个个语法应该是微软的nmake吧.

#5


$(OBJPATH)\%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < 
---------------------------------
$(OBJPATH)\%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < ; mv $(OBJPATH)\..\src\%.obj $(OBJPATH)\%.obj


再试试看,可以用分号分隔的

#6


关键不在于$(OBJPATH)\%.obj:%.cpp  的表达,在于可以连续执行多个命令

#7


不好意思,我还真不了解微软的什么nmake。

我在Linux上面写Makefile就是一直这么写的。

一般写Makefile都难免会做一些简单的调试,
但是因为我没有你的工作环境,
所以只能结合你所给出的上下文中的变量以及写法来给出我的改法。
而无法帮你对Makefile进行调试。

#8


谢谢各位, 但还是不能解决我的问题:

实际上: 在link的时候是要指明obj的目录的, 这是因为不在当前目录中.所以, 在link的命令中就需要指定obj的目录, 例如: ..\obj\bims.obj
由于该obj文件是令一个编译指令的目标. 而该目标的规则就是应该是如下的样子:

..\obj\bims.obj:bims.cpp
    cl ..... (进行编译)

问题是: 当我使用模式规则时, 该模式规则也应该能展开成如上的样子. 否则, 就是会提示, 没有目标(..\obj\bims.obj)的生成规则.
因此, 需要在模式规则中指定目标的路径.

同时,我将在C++板块中再建立该帖子. 清除描述该问题.

#9


CXX) $(CXXFLAGS) $  <

在展开后难道不应该是

cc -c -o xxx.o xxx.cpp 么?
 
你不要使用<

而是指定文件名不行么?
让它展开成
cc -c -o ../obj/xxx.o xxx.cpp

#10


楼上的兄弟, 我的问题不在于编译指令的展开, 而是期望规则展开后, 目标文件能具备路径.
简单的说, 我希望推导规则展开后, 能等价与:
..\obj\bims.obj:bims.cpp

该问题已经转移到C++语言的工具主题中, 100分. 链接为:
http://topic.csdn.net/u/20080516/15/811bd346-9860-4a18-86fe-495e0359807f.html

#11


……

貌似你搞错了。我在这里跟帖子不是为了分。
这里是大家相互交流技术的平台。

感觉你已经不是实际应用中遇到了问题,而在这里讨论了。倒像是吵闹着要考试题目答案的。
抱歉,帮不了你。

希望你能够及时地得到你想要得答案。

#12


呵呵, 谢谢. 的确是实际应用中出现的问题, 目前我对每个源码文件的编译都是独立的编写规则. 我感觉这样维护大的项目比较麻烦, 当我了解了模式规则后, 我想用模式规则来实现所有源码的编译问题.
网上有很多make的手册, 但对此避而不谈. 我不知道这是为什么. 难道大家都没有这样的需求?

答案我还没有找到, 但你说的对, 我是着急要答案了. 呵呵. 下步改正.

#13


个人觉得你的以$(OBJPATH)\%.obj作为目标的做法非常怪异,
建议你多看看例子以后再来说你了解了所谓的模式规则

你的需求很简单,用一般的Make install的做法就可以做到,
也就是先生成后拷贝的办法来做到

但是当你给出这样一个目标的定义OBJS = $(OBJPATH)\bims_core.obj 的时候,
就说明你的思维和一般的Makefile的做法完全处于两个方向上了,
不要怪别人没有给你答案,
是人家已经给了你接近答案的思路但是你还是陷在你自己的想法里面不能自拔.
并且你至今都无法认识到你的做法是属于非常规做法.

也许是基础还很薄弱所以无法认识到这种做法的非常规性,
但也可能是一种创新.
创新的话令人欣赏,
但是人为将简单问题复杂化则不可取.

祝你好运.

#14


不清楚楼主的大的项目是个什么概念。
从我接触到的中间件项目来说,如13楼所说,make install的方法用得比较多。

关于模式规则,你可以参考下make的联机帮助。或者说,再研究下shell的语法,应该对你有所帮助。(B或者C都可以,因为make可以通过环境变量定制内部shell环境的。)

再具体点说:$(OBJPATH)\%.obj是你的目标,但是实现目标的手段是$(CXX) $(CXXFLAGS) $  <,而不是$(OBJPATH)\%.obj。
你执著在目标上,舍本逐末了。

#1


少建一个 gcc-build 目录 
mkdir /mnt/lfs/sources/gcc-build

#2


不是吧, 我是在windows平台上用的make, 并且我只是想让模式规则自动推导成:

..\objs\bims.obj:bims.cpp

bims.cpp就是当前目录下的文件. 问题是我如何能用模式规则实现上面的一般推导规则.

#3


试试看将下面这段改掉:
-------------------
$(OBJPATH)\%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < 

%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < 
-------------------
改成:
-------------------
.cpp.o:
$(CXX) $(CXXFLAGS) $<
mv $< $(OBJPATH)
-------------------

#4


噢, 对不起, 我用的是GNU Make 3.81版本, 是从MingW中获得的. 你的这个个语法应该是微软的nmake吧.

#5


$(OBJPATH)\%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < 
---------------------------------
$(OBJPATH)\%.obj:%.cpp 
$(CXX) $(CXXFLAGS) $ < ; mv $(OBJPATH)\..\src\%.obj $(OBJPATH)\%.obj


再试试看,可以用分号分隔的

#6


关键不在于$(OBJPATH)\%.obj:%.cpp  的表达,在于可以连续执行多个命令

#7


不好意思,我还真不了解微软的什么nmake。

我在Linux上面写Makefile就是一直这么写的。

一般写Makefile都难免会做一些简单的调试,
但是因为我没有你的工作环境,
所以只能结合你所给出的上下文中的变量以及写法来给出我的改法。
而无法帮你对Makefile进行调试。

#8


谢谢各位, 但还是不能解决我的问题:

实际上: 在link的时候是要指明obj的目录的, 这是因为不在当前目录中.所以, 在link的命令中就需要指定obj的目录, 例如: ..\obj\bims.obj
由于该obj文件是令一个编译指令的目标. 而该目标的规则就是应该是如下的样子:

..\obj\bims.obj:bims.cpp
    cl ..... (进行编译)

问题是: 当我使用模式规则时, 该模式规则也应该能展开成如上的样子. 否则, 就是会提示, 没有目标(..\obj\bims.obj)的生成规则.
因此, 需要在模式规则中指定目标的路径.

同时,我将在C++板块中再建立该帖子. 清除描述该问题.

#9


CXX) $(CXXFLAGS) $  <

在展开后难道不应该是

cc -c -o xxx.o xxx.cpp 么?
 
你不要使用<

而是指定文件名不行么?
让它展开成
cc -c -o ../obj/xxx.o xxx.cpp

#10


楼上的兄弟, 我的问题不在于编译指令的展开, 而是期望规则展开后, 目标文件能具备路径.
简单的说, 我希望推导规则展开后, 能等价与:
..\obj\bims.obj:bims.cpp

该问题已经转移到C++语言的工具主题中, 100分. 链接为:
http://topic.csdn.net/u/20080516/15/811bd346-9860-4a18-86fe-495e0359807f.html

#11


……

貌似你搞错了。我在这里跟帖子不是为了分。
这里是大家相互交流技术的平台。

感觉你已经不是实际应用中遇到了问题,而在这里讨论了。倒像是吵闹着要考试题目答案的。
抱歉,帮不了你。

希望你能够及时地得到你想要得答案。

#12


呵呵, 谢谢. 的确是实际应用中出现的问题, 目前我对每个源码文件的编译都是独立的编写规则. 我感觉这样维护大的项目比较麻烦, 当我了解了模式规则后, 我想用模式规则来实现所有源码的编译问题.
网上有很多make的手册, 但对此避而不谈. 我不知道这是为什么. 难道大家都没有这样的需求?

答案我还没有找到, 但你说的对, 我是着急要答案了. 呵呵. 下步改正.

#13


个人觉得你的以$(OBJPATH)\%.obj作为目标的做法非常怪异,
建议你多看看例子以后再来说你了解了所谓的模式规则

你的需求很简单,用一般的Make install的做法就可以做到,
也就是先生成后拷贝的办法来做到

但是当你给出这样一个目标的定义OBJS = $(OBJPATH)\bims_core.obj 的时候,
就说明你的思维和一般的Makefile的做法完全处于两个方向上了,
不要怪别人没有给你答案,
是人家已经给了你接近答案的思路但是你还是陷在你自己的想法里面不能自拔.
并且你至今都无法认识到你的做法是属于非常规做法.

也许是基础还很薄弱所以无法认识到这种做法的非常规性,
但也可能是一种创新.
创新的话令人欣赏,
但是人为将简单问题复杂化则不可取.

祝你好运.

#14


不清楚楼主的大的项目是个什么概念。
从我接触到的中间件项目来说,如13楼所说,make install的方法用得比较多。

关于模式规则,你可以参考下make的联机帮助。或者说,再研究下shell的语法,应该对你有所帮助。(B或者C都可以,因为make可以通过环境变量定制内部shell环境的。)

再具体点说:$(OBJPATH)\%.obj是你的目标,但是实现目标的手段是$(CXX) $(CXXFLAGS) $  <,而不是$(OBJPATH)\%.obj。
你执著在目标上,舍本逐末了。