【问题标题】:Makefile that generates obj files in subdirectory in Windows nmake在 Windows nmake 的子目录中生成 obj 文件的 Makefile
【发布时间】:2015-08-06 13:15:24
【问题描述】:

我正在使用 nmake 来编译使用 makefile 的程序。我正在尝试将 obj (.o) 文件放置在与 C 文件不同的目录中。这是生成文件:

!IFDEF DEBUG
COPT = $(CFLAGS_LIB) $(CDEBUGFLAG) $(LIB_OPTION)
AOPT = $(AFLAGS_LIB) $(ADEBUGFLAG) $(LIB_OPTION)
!ELSE
COPT = $(CFLAGS_LIB) $(CNODBGFLAG) $(LIB_OPTION)
AOPT = $(AFLAGS_LIB) $(ANODBGFLAG) $(LIB_OPTION)
!ENDIF

#################### Collect build files #####################################

CORE_HDRS =           \
    i_core.h          \
    i_cver.h          \
    i_target.h        \
    i_subbus.h        \
    v_core.h          \
    v_ioctl.h         \
    v_subbus.h        \
    v_target.h        \
    volcano6.h

CORE_OBJS =           \
    $(OBJPATH)/v_activable.$(O) \
    v_busoff_int.$(O) \
    v_c_act.$(O)  \
    v_c_con.$(O)  \
    v_c_dis.$(O)  \
    v_c_ini.$(O)  \

查看 CORE_OBJS 我将 $(OBJDIR) 与第一个目标文件一起使用,而其余的则没有前缀。 问题是 $(OBJPATH)/v_activable.$(O) 根本没有编译。编译其余文件并将 .o 文件放在与 .c 文件相同的目录中。 这是编译代码的代码 ma​​kefile 部分。

OBJS = $(CORE_OBJS)


all: __prebuild__ __library__ __postbuild__

__prebuild__:
    @echo ----------------------------------------------------------------
    @echo "********************* Build started ****************************"

__dispopts__:
    @echo '*** Compiler: $(CC)'
    @echo "*** Compiler options: $(COPT)"
    @echo "*** Assembler options: $(AOPT)"
    @echo '*** Archiver: $(AR)'
    @echo "*** Archiver options: $(ARFLAGS)"
    @echo ----------------------------------------------------------------
    @echo "******************** Code generation ***************************"

__postbuild__:
    @echo ----------------------------------------------------------------
    @echo "********************* Build finished ***************************"

__library__: __dispopts__ $(OBJS)
    @echo ----------------------------------------------------------------
    @echo "******************** Creating library **************************"
    -@$(AR) $(ARFLAGS)
#################### Inference rules #########################################

.c.$(O):
    @echo Compiling $<
    @$(CC) $(COPT) $<

.$(S).$(O):
    @echo Assembling $<
    @$(AS) $(AOPT) $<

任何人都可以看看并告诉我到底是什么问题。我试过规则:

$(OBJPATH)/%.o : $(SRC_DIR)/%.c

但 nmake 无法识别此规则。 这是编译器选项

CFLAGS_LIB = -D__FAR_DATA -DUSE_LARGE_IMMEDIATE_FRAME_MASK -CpuHCS12X -Cc -Mb -Wpd -F2 -Rpt -Ot -Onu -Onf -Ol0 -OnB -Onbt -Onca -Oncn -One -OnP -Ont $(SUPPRESSIONS)

CNODBGFLAG = -NoDebugInfo -NoPath


COPT = $(CFLAGS_LIB) $(CNODBGFLAG)

【问题讨论】:

  • NMAKE 通常用于 Window 平台。在 Windows 文件路径上使用“\”符号,命令选项使用“/”符号。在 linux 和 Mac 上,文件路径使用“/”符号,选项通常使用“-”符号。我看到您在路径中使用“/”符号。这在 NMAKE 中是不正常的。也许这是你的问题?
  • 感谢您的回答。我同时使用了“/”、“\”。但问题仍然存在。实际上,当我为 obj 文件指定一些路径时,编译器希望源文件位于同一目录中。但我想要不同目录中的源文件和目标文件。
  • 您使用的是哪个编译器和汇编器?编译命令不会更改对象文件夹。要更改它,我们需要知道哪些编译器。是 GCC、CL 还是什么?
  • 我正在使用来自 diab 5.9.1.6 的编译器

标签: c makefile subdirectory nmake object-files


【解决方案1】:

我没有 The Diab 或 CGT 编译器工具,因此无法测试我的建议,但很明显您的 makefile 没有使用 correct options 来重定向目标文件。

我假设宏 OBJPATH 是您希望编译器将对象发送到的位置。

如果是这种情况,那么您需要将其添加到 每个 对象文件的名称中,如下所示:

CORE_OBJS =           \
    $(OBJPATH)\v_activable.$(O) \
    $(OBJPATH)\v_busoff_int.$(O) \
    $(OBJPATH)\v_c_act.$(O)  \
    $(OBJPATH)\v_c_con.$(O)  \
    $(OBJPATH)\v_c_dis.$(O)  \
    $(OBJPATH)\v_c_ini.$(O)  

请注意,我们将\ 符号用于两种不同的目的。这在Microsoft documentation 中有说明。

下一个必须更改的部分是编译器标志,用于将对象重定向到所需位置。这可以在这里完成:

COPT = $(CFLAGS_LIB) $(CNODBGFLAG) -c -o $@

这是使用target macros as shown in the documentation

对于CGT compiler the options are expressed as --out=,规则是:

COPT = $(CFLAGS_LIB) $(CNODBGFLAG) --compile-only --out=$@

不需要为编译添加进一步的规则,因为这里已经处理了:

.c.$(O):
        @echo Compiling $<
        @$(CC) $(COPT) $<

但是,这需要修改为add the directories where the files reside。最好的来源是this answer。因此,应将其修改为:

{$(SRC_DIR)}.c{$(OBJPATH)}.$(O):
        @echo Compiling $<
        @$(CC) $(COPT) $<

最后,just in case your suffix $(O) is different to the standards recognised by nmake 可能是明智的confirm the suffixes with the directive

.SUFFIXES: .c .$(O)

所以你添加的这条规则:

$(OBJPATH)/%.o : $(SRC_DIR)/%.c

通过使用错误的路径和覆盖现有规则使情况变得更糟,因此应该删除。

我现在已经在 makefile 中对此进行了测试,以防我忽略了某些内容,并且它适用于我的测试文件。由于我不使用汇编程序,我的 makefile 版本被简化了,但它确实证明了它可以根据需要在不同的目录中维护源和对象。 More changes would need to be made to link the objects into the library by using appropriate options for the linker.我用gcc 模拟了这个:

!IFDEF DEBUG
COPT = $(CFLAGS_LIB) $(CDEBUGFLAG) $(LIB_OPTION) 
AOPT = $(AFLAGS_LIB) $(ADEBUGFLAG) $(LIB_OPTION) 
!ELSE
COPT = $(CFLAGS_LIB) $(CNODBGFLAG) $(LIB_OPTION)
AOPT = $(AFLAGS_LIB) $(ANODBGFLAG) $(LIB_OPTION) 
!ENDIF

#################### Collect build files #####################################

# Set macro for object file type
O=o
OBJPATH=obj
SRC=src
AR=gcc
ARFLAGS=-o library.exe $(OBJS)     

CORE_OBJS =           \
    $(OBJPATH)\one.$(O) \
    $(OBJPATH)\two.$(O) 

#append flag for directing object to their directory

COPT = $(COPT) -c -o $@

OBJS = $(CORE_OBJS)

.SUFFIXES: .c .$(O)


all: __prebuild__ __library__ __postbuild__

__prebuild__:
    @echo ----------------------------------------------------------------
    @echo "********************* Build started ****************************"

__dispopts__:
    @echo '*** Compiler: $(CC)'
    @echo "*** Compiler options: $(COPT)"
    @echo "*** Assembler options: $(AOPT)"
    @echo '*** Archiver: $(AR)'
    @echo "*** Archiver options: $(ARFLAGS)"
    @echo ----------------------------------------------------------------
    @echo "******************** Code generation ***************************"

__postbuild__:
    @echo ----------------------------------------------------------------
    @echo "********************* Build finished ***************************"

__library__: __dispopts__ $(OBJS)
    @echo ----------------------------------------------------------------
    @echo "******************** Creating library **************************"
    -@$(AR) $(ARFLAGS) 
#################### Inference rules #########################################



{src}.c{$(OBJPATH)}.$(O):
    @echo Compiling $(CC) $(COPT) $<
    @$(CC) $(COPT) $<

输出显示构建和链接工作:

C:\Users\Brian>nmake /nologo /f Makefile
----------------------------------------------------------------
"********************* Build started ****************************"
'*** Compiler: gcc'
"*** Compiler options:    -c -o __dispopts__"
"*** Assembler options:   "
'*** Archiver: gcc'
"*** Archiver options: -o library.exe obj\one.o  obj\two.o"
----------------------------------------------------------------
"******************** Code generation ***************************"
Compiling gcc -c -o obj\one.o src\one.c
Compiling gcc -c -o obj\two.o src\two.c
----------------------------------------------------------------
"******************** Creating library **************************"
----------------------------------------------------------------
"********************* Build finished ***************************"

【讨论】:

  • 嗨,Brian,我再次尝试了这个,但问题仍然存在。 $(OBJPATH)/%.o : $(SRC_DIR)/%.c 此规则无效。编译器期望源文件与目标文件位于同一文件夹中。而这个问题不在编译器中。现在我已经改变了编译器。现在我正在使用 Code Composer Studio 的“cgt”。
  • @MuhammadImranAfzal 我现在已经修复了答案并包含了有关使用 CGT 编译器的详细信息。
  • 嗨,布赖恩,非常感谢您的回答。但是我对这件事仍然有一些问题。您能否发送/发布您的测试程序。可能是我错过了一些东西。感谢您对这个主题进行如此广泛而详细的搜索。
  • @MuhammadImranAfzal 我的示例 makefile 现在已添加
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多