5

我们有一个在 Windows 2003 机器上运行的 Makefile,我们正在使用 mingw32-make。由于 Makefile 有许多包含路径,它超过了 cmd 可以处理的 8K 缓冲区大小 [Ref - http://support.microsoft.com/kb/830473/EN-US/由于编译结果为“输入行太长”的问题。

我想知道以下内容 -

  1. 什么是优化 Makefile 的最佳方法,因为我已经删除了不需要的编译器开关、包含路径等。

  2. 有什么方法可以将所有 INCLUDE 路径放在一个 .txt 文件中并将其导入 Makefile。我找不到任何 mingw32 文档。

欢迎任何其他输入/提示/参考链接

谢谢,
-HJSblogger

4

2 回答 2

4

我们采取的一种方法(这不是因为我们用完了命令行空间,只是因为我们想要一个更干净的构建系统)是让每个“模块”都进行构建。

因此,例如,假设您有 3 个模块,A、B 和 C。

您的控制生成文件只需调用具有相同目标的每个模块生成文件。

然后我们将目标设置为一致的 clean、header、lib 和 exec。

因此,控制 makefile 类似于:

modules=A B C
clean:
    for i in $modules:
        ( cd $i ; make clean ; cd .. )
header:
    for i in $modules:
        ( cd $i ; make header ; cd .. )
lib:
    for i in $modules:
        ( cd $i ; make lib ; cd .. )
exec:
    for i in $modules:
        ( cd $i ; make exec ; cd .. )

每个具有其他模块所需头文件的模块都在头阶段将这些头文件复制到一个中心位置。然后,在 lib 或 exec 阶段,每个模块只需使用该中心位置来定位其所有头文件。这也将模块限制为仅使用由其他模块发布到中心位置的那些标头。

同样,创建 exec 阶段所需的库的每个模块都将该库复制到中心位置。这极大地减少了构建命令中的-I(include directory) 和-L(library directory) 子句。

使用该方案,您可以通过make clean header lib exec在顶层执行来重建整个事物(或者clean考虑到依赖关系,放弃正确的 make 构建)。

这是解决您的问题的一种方法,但我实际上想知道是如何超出限制的。8K,即使每个路径有 25 个字符,也需要大约 300 个不同的包含路径。你的层次结构真的那么庞大吗?

更新1:

如果您正在寻找一种不改变makefile“架构”的快速'n'dirty方法让它工作,你编写一个脚本,给定一个目录列表,将所有头文件从这些目录复制到一个中心位置。

然后将其作为所有规则的第一步运行,并修改编译行中的包含语句以仅引用该位置而不是大列表。您甚至可以分阶段进行复制(例如,一次 20 个目录 x 20 次总共可以处理 400 个目录)。

这为您提供与我提出的解决方案相同的效果,只需对 makefile 进行较小的更改。

更新 2:

正如您在评论中所述,另一种解决方案是为路径命名。

你应该能够做到这一点,subst.exe例如:

> subst x: "c:\Documents and Settings\Pax\My Documents\Not my directory"
> dir x:
  Volume in drive X has no label.
  Volume Serial Number is 8AA3-703A

  Directory of X:\

  08/09/2009  10:12 AM    <DIR>          .
  08/09/2009  10:12 AM    <DIR>          ..
  24/08/2009  01:54 PM             6,409 p0rn_sites.txt
  09/07/2008  02:49 PM    <DIR>          downloaded_p0rn
  : : :
  09/07/2008  02:52 PM    <DIR>          other_suspect_stuff
                 3 File(s)         18,520 bytes
                18 Dir(s)  63,840,849,920 bytes free

> subst x: /d
> dir x:
  The system cannot find the path specified.
于 2009-09-08T06:25:40.927 回答
0

使用“make”的 NACL SDK 版本我遇到了“命令行太长”的问题。

问题的原因是 Windows shell (cmd.exe) 在命令行中有 8191 字符大小限制:http: //support.microsoft.com/kb/830473/en

问题是当编译到使用“ar”创建库时,源文件太多,命令行太长。

所以,为了解决这个问题,我不得不更改“nacl_llvm.mk”文件:

#
# LIB Macro
#
# $1 = Target Name
# $2 = List of Sources
# $3 = POSIX Link Flags
# $4 = VC Link Flags (unused)
define LIB_RULE
$(STAMPDIR)/$(1).stamp: $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a
    @echo "TOUCHED $$@" > $(STAMPDIR)/$(1).stamp

all: $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a
$(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a: $(foreach src,$(2),$(call SRC_TO_OBJ,$(src)))
    $(MKDIR) -p $$(dir $$@)
    $(RM) -f $$@
# Comment this line!    
#    $(call LOG,LIB,$$@,$(PNACL_LIB) -cr $$@ $$^ $(3))

# Add these other lines
    $(shell echo cmd /C $(subst /,\,$(PNACL_LIB) -cr $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a) > create_lib.bat)
    $(foreach src,$(2),$(shell echo cmd /C $(subst /,\,$(PNACL_LIB) -r $(LIBDIR)/$(TOOLCHAIN)/$(CONFIG)/lib$(1).a $(call SRC_TO_OBJ,$(src))) $(3) >> create_lib.bat))
    create_lib.bat

endef

这个想法是创建一个“bat”文件,其中包含创建库文件必须执行的所有命令,然后一一添加目标文件。之后,“bat”文件在适当的时候执行。

此致

于 2015-01-29T13:54:31.260 回答