mingw32-make : “输入行太长”问题

发布于 2024-08-04 16:08:35 字数 519 浏览 3 评论 0原文

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

我想知道以下内容 -

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

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

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

谢谢,
-HJS博主

We have a Makefile which runs on a Windows 2003 machine and we are using mingw32-make for it. Since the Makefile has many include paths, it exceeds the buffer size of 8K that the cmd can handle [Ref - http://support.microsoft.com/kb/830473/EN-US/due to which the compilation results in "input line too long" issue.

I wanted to know the following -

  1. What would be the best way to optimize the Makefile as I have already removed unwanted compiler switches, include paths etc.

  2. Is there any way we can put all the INCLUDE paths in one .txt file and import it in the Makefile.I could not find any mingw32 documentation for the same.

Any other inputs/hints/reference links are most welcome.

Thanks,
-HJSblogger

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对不⑦ 2024-08-11 16:08:35

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

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

您的控制 makefile 只需调用具有相同目标的每个模块 makefile。

然后我们将目标设置为一致的 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 (包含目录)和 -L (库目录)子句。

使用该方案,您只需在顶层执行 make clean header lib exec 即可重建整个内容(或者省略 clean 进行正确的 make 构建,考虑到考虑依赖性)。

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

更新1:

如果您正在寻找一种快速而肮脏的方法来使其工作而不更改makefile“体系结构”,您可以编写一个脚本,在给定目录列表的情况下,该脚本将复制所有目录头文件从这些目录到一个中心位置。

然后将其作为所有规则的第一步运行,并修改编译行中的 include 语句以仅引用该位置而不是大列表。您甚至可以分阶段进行复制(例如,一次 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.

One approach we took (this wasn't because we ran out of command-line space, just because we wanted a cleaner build system) was to have each "module" do its build in passes.

So, for example, say you have 3 modules, A, B and C.

Your control makefile simply calls each modules makefile with the same target.

Then we set the targets to be a consistent clean, header, lib and exec.

So, the control makefile was something like:

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 .. )

Every module that had header files needed by other modules copied those header files into a central location during the header phase. Then, during the lib or exec phase, each module only had to use that central location to locate all of its headers. This also restricted modules to only using those headers that were published to the central location by other modules.

Similarly, every module that created a library needed by the exec phase, copied that library to a central location. This greatly minimized the -I (include directory) and -L (library directory) clauses in the build commands.

Using that scheme, you could rebuild the entire thing just by executing make clean header lib exec at the top level (or leave off the clean for a proper make build, taking into account the dependencies).

That's one way to get around your problem, but I'm actually wondering how you're exceeding the limit. 8K, even at 25 characters per path, would require about 300 distinct include paths. Is your hierarchy really that voluminous?

Update 1:

If you're looking for a quick'n'dirty way to get it working without changing the makefile "architecture", you write a script which, given a list of directories, will copy all header files from those directories to a central location.

Then run that as the first step in all your rules and modify the include statements in your compile lines to just reference that location rather than the large list. You could even do the copy in stages (e.g., 20 directories at a time x 20 times could handle 400 directories in total).

This gives you the same effect as my proposed solution with smaller changes to the makefiles.

Update 2:

One other solution, as you stated in your comments, was to alias a path.

You should be able to do that with subst.exe such as:

> 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.
长梦不多时 2024-08-11 16:08:35

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

问题的原因是 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”文件就会在适当的时候执行。

此致

using the NACL SDK version of "make" I had the "command line is too long" problem.

The cause of the problem is that Windows shell (cmd.exe) has a 8191 char size limitation in command line:
http://support.microsoft.com/kb/830473/en

The problem was that when the compilation reaches the point of creating a library by using "ar", there were too much source files and command line was too long.

So, to solve this, I had to change the "nacl_llvm.mk" file:

#
# 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

The idea is to create a "bat" file with all the commands that must be executed to create the library file and then add the object files one by one.
After that the "bat" file is executed at the right moment.

Best regards

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文