为了账号安全,请及时绑定邮箱和手机立即绑定

如何将目标文件放在单独的子目录中

如何将目标文件放在单独的子目录中

我在尝试使用make将目标文件放在单独的子目录中时遇到麻烦,这可能是一种非常基本的技术。我试图使用此页面中的信息:http : //www.gnu.org/software/hello/manual/make/Prerequisite-Types.html#Prerequisite-Types我从make得到以下输出:make: *** No rule to make target `ku.h', needed by `obj/kumain.o'.  Stop.但是ku.h不是目标而是依赖关系(尽管它显然已#include在c源文件中)。当我不尝试使用子目录存储目标文件时(即错过OBJDIR部分),它可以正常工作。为什么使ku.h是目标?我的makefile是这样的:(样式是在阅读了各种信息源之后的).SUFFIXES:.SUFFIXES: .c .oCC=gcc CPPFLAGS=-WallLDLIBS=-lhpdfVPATH=%.c srcVPATH=%.h srcVPATH=%.o objOBJDIR=objobjects= $(addprefix $(OBJDIR)/, kumain.o kudlx.o kusolvesk.o kugetpuz.o kuutils.o \  kurand.o kuASCboard.o kuPDFs.o kupuzstrings.o kugensud.o \  kushapes.o )ku : $(objects)  $(CC) $(CPPFLAGS) -o ku $(objects) $(LDLIBS)$(objects) : ku.h kudefines.h kuglobals.h kufns.h | $(OBJDIR)$(OBJDIR):  mkdir $(OBJDIR).PHONY: cleanclean :  rm $(objects)编辑:我应用更改以使用vpath指令。我的版本是VPATH = xxx和vpath%.c xxx的不良混合。但是,我现在遇到了另一个问题(这是我添加错误的vpath之前的原始问题)。现在是输出:    gcc  -o ku -lhpdf obj/kumain.o obj/kudlx.o obj/kusolvesk.o ..etc    gcc: obj/kumain.o: No such file or directory    gcc: obj/kudlx.o: No such file or directory    gcc: obj/kusolvesk.o: No such file or directory    gcc: obj/kugetpuz.o: No such file or directory    gcc: obj/kuutils.o: No such file or directory    gcc: obj/kurand.o: No such file or directory    gcc: obj/kuASCboard.o: No such file or directory    gcc: obj/kuPDFs.o: No such file or directory    gcc: obj/kupuzstrings.o: No such file or directory    gcc: obj/kugensud.o: No such file or directory    gcc: obj/kushapes.o: No such file or directory    make: *** [ku] Error 1尽管手册中说“隐式规则告诉make如何使用惯用技术,以便您不必在使用它们时详细指定它们,但make似乎并未将隐式规则应用于目标文件。是C编译的隐式规则,文件名决定运行哪些隐式规则,例如,C编译通常需要一个.c文件并创建一个.o文件,因此当make看到此组合时,make将隐式规则应用于C编译。文件名结尾。” 以及“在考虑隐式规则的过程中也会发生在VPATH或vpath中指定目录的搜索(请参阅使用隐式规则)。”再次在此处“例如,当文件foo.o没有显式规则时,make考虑隐式规则,例如内置规则,以编译foo.c(如果该文件存在。如果当前目录中缺少该文件,在适当的目录中进行搜索。如果在任何目录中都存在foo.c(或在makefile中提到),则将应用C编译的隐式规则。”在使隐式规则适用于我的makefile方面的任何帮助将不胜感激。
查看完整描述

3 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

由于您使用的是GNUmake,因此请使用模式规则来编译目标文件:


$(OBJDIR)/%.o: %.c

    $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<


查看完整回答
反对 回复 2019-10-08
?
慕哥6287543

TA贡献1831条经验 获得超10个赞

这是我用于大多数项目的makefile,


它允许将源文件,头文件和内联文件放在子文件夹以及子文件夹的子文件夹等中,并会自动为每个对象生成一个依赖文件。这意味着对头文件和内联文件的修改将触发对相关文件的重新编译。


通过shell find命令检测到源文件,因此无需明确指定,只需对您的内容进行编码即可。


编译项目时,它还将所有文件从“资源”文件夹复制到bin文件夹中,而我在大多数情况下都很方便。


为了提供应有的信誉,自动依赖功能主要基于Scott McPeak的页面(可在此处找到),并进行了一些其他修改/调整以满足我的需求。


示例文件


#Compiler and Linker

CC          := g++-mp-4.7


#The Target Binary Program

TARGET      := program


#The Directories, Source, Includes, Objects, Binary and Resources

SRCDIR      := src

INCDIR      := inc

BUILDDIR    := obj

TARGETDIR   := bin

RESDIR      := res

SRCEXT      := cpp

DEPEXT      := d

OBJEXT      := o


#Flags, Libraries and Includes

CFLAGS      := -fopenmp -Wall -O3 -g

LIB         := -fopenmp -lm -larmadillo

INC         := -I$(INCDIR) -I/usr/local/include

INCDEP      := -I$(INCDIR)


#---------------------------------------------------------------------------------

#DO NOT EDIT BELOW THIS LINE

#---------------------------------------------------------------------------------

SOURCES     := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))

OBJECTS     := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)))


#Defauilt Make

all: resources $(TARGET)


#Remake

remake: cleaner all


#Copy Resources from Resources Directory to Target Directory

resources: directories

    @cp $(RESDIR)/* $(TARGETDIR)/


#Make the Directories

directories:

    @mkdir -p $(TARGETDIR)

    @mkdir -p $(BUILDDIR)


#Clean only Objecst

clean:

    @$(RM) -rf $(BUILDDIR)


#Full Clean, Objects and Binaries

cleaner: clean

    @$(RM) -rf $(TARGETDIR)


#Pull in dependency info for *existing* .o files

-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))


#Link

$(TARGET): $(OBJECTS)

    $(CC) -o $(TARGETDIR)/$(TARGET) $^ $(LIB)


#Compile

$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)

    @mkdir -p $(dir $@)

    $(CC) $(CFLAGS) $(INC) -c -o $@ $<

    @$(CC) $(CFLAGS) $(INCDEP) -MM $(SRCDIR)/$*.$(SRCEXT) > $(BUILDDIR)/$*.$(DEPEXT)

    @cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp

    @sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)

    @sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)

    @rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp


#Non-File Targets

.PHONY: all remake clean cleaner resources


查看完整回答
反对 回复 2019-10-08
  • 3 回答
  • 0 关注
  • 944 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信