我们有一个在Windows 2003机器上运行的Makefile,我们正在使用mingw32-make。由于Makefile有许多包含路径,因此它超过了cmd可以处理的8K的缓冲区大小[Ref - http://support.microsoft.com/kb/830473/EN-US/,因为编译会导致“输入行太长”问题。
我想知道以下内容 -
优化Makefile的最佳方法是什么,因为我已经删除了不需要的编译器开关,包括路径等。
有没有办法可以将所有INCLUDE路径放在一个.txt文件中并将其导入Makefile。我找不到任何mingw32文档。
欢迎任何其他输入/提示/参考链接。
谢谢,
-HJSblogger
答案 0 :(得分:4)
我们采取的一种方法(这不是因为我们用完了命令行空间,只是因为我们想要一个更清晰的构建系统)是让每个“模块”在传递中进行构建。
因此,例如,假设您有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.
答案 1 :(得分:0)
使用&#34;制作&#34;的NACL SDK版本我的&#34;命令行太长&#34;问题
问题的原因是Windows shell(cmd.exe)在命令行中具有8191字符大小限制: http://support.microsoft.com/kb/830473/en
问题在于,当编译到达使用&#34; ar&#34;创建库时,源文件太多而命令行太长。
所以,为了解决这个问题,我不得不改变&#34; nacl_llvm.mk&#34;文件:
#
# 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
这个想法是创造一个&#34; bat&#34;文件包含必须执行的所有命令以创建库文件,然后逐个添加目标文件。 之后&#34; bat&#34;文件在合适的时刻执行。
祝你好运