【发布时间】:2016-06-02 07:41:15
【问题描述】:
我有一个(旧版)bash 脚本,它解析源文件的目录列表并将它们回显到生成文件中,以使用gcc -MM 创建实际的生成规则。该脚本运行良好,问题是在生成的 makefile 上运行 make 会导致 makerules 中的路径格式不一致 - 虽然大多数 makerules 具有混合样式路径(可以),但有些具有 cygwin 样式路径(不可以)。这在 cygwin 的一个非常老的(~2002 版本)上没有发生。
这是脚本:
#!/bin/bash
fn_source=SourceFileList
fn_depmake=depMakefile
fn_orgMake=Makefile
fn_depIncl=Depend.incl
fn_optIncl=OptimizationCflags.incl
#
# create a Makefile to determine the dependencies
echo -n create dep-makefile ...\
#
# generate include for Optimization-File
#
echo > $fn_depIncl
echo include $fn_optIncl >> $fn_depIncl
echo >> $fn_depIncl
#
touch $fn_optIncl
#
echo > $fn_depmake
# CFLAGS options from Makefile
grep "^CFLAGS[ =]" $fn_orgMake | grep $BUILD_SPEC >> $fn_depmake
grep "^CFLAGS_AS[ =]" $fn_orgMake | grep $BUILD_SPEC >> $fn_depmake
grep "^CFLAGS_GCC[ =]" $fn_orgMake | grep $BUILD_SPEC >> $fn_depmake
echo -n generate depMakefile ...
echo >> $fn_depmake
# the default rule
echo all: >> $fn_depmake
FileList=`cat $fn_source`
incPath=""
rawIncPath=""
for fn in $FileList; do
incPath=$incPath" -I"${fn%/*}
rawIncPath=$rawIncPath" "${fn%/*}
done
# filter out redundant paths
echo $incPath | \
sed -n -e 's/ /\
/gp' | \
sort -u > _tmp
incPath=`cat _tmp`
# filter out redundant paths
echo $rawIncPath | \
sed -n -e 's/ /\
/gp' | \
sort -u > _tmp
rawIncPath=`cat _tmp`
#
# create file with include paths
#
echo LibIncludes=$incPath > LibIncludes
#
# put all source files with the same path in one gcc command
#
for path in $rawIncPath; do
sourceFiles=`grep $path/ $fn_source`
echo " "echo do $path >> $fn_depmake
echo " "gcc -MM '$(CFLAGS_GCC)' -I$path $sourceFiles \>\> _tmp >> $fn_depmake
done
# start the Makefile
echo start Makefile ...
rm _tmp; touch _tmp
make -s -f $fn_depmake
# add ./obj/xxxxx*.o to the make-rules
sed -e 's/\(^[a-zA-Z]\)/.\/obj\/\1/' < _tmp > _tmp1
# add command to the make-rules
sed -e '/\\/!a\
$(CC) $($(*F)CFLAGS) -I$(<D) $(CFLAGS) -c $< -o $@' < _tmp1 >> $fn_depIncl
# workaround for gcc generating cygdrive paths for some paths only
sed -i 's#/cygdrive/d#d:#' $fn_depIncl
rm _tmp _tmp1
rm $fn_depmake
echo done.
如您所见,我目前正在使用一种解决方法将这些路径转换为使用 sed 的混合样式的路径,但我想知道为什么会发生这种情况?
“错误”的规则示例:
some.o: d:/some/path/A/some.cpp \
d:/some/path/A/some.h \
/cygdrive/d/some/path/B/subpathA/anotherheader.h \
/cygdrive/d/some/path/B/subpathA/yetanotherheader.h \
D:/some/path/B/subpathB/header.h
这方面的主要问题是生成的 makefile 被馈送到 Windows 本机 make.exe,它不知道 /cygdrive/d/path 应该是什么。
我查看了每一步之后的路径,它们都是混合样式直到make -s -f $fn_depmake被执行。这意味着,偶尔转换为 cygwin 样式路径是由生成的 makefile 中的gcc -MM 命令完成的。
转换为/cygdrive/d/pathA/somefile.cpp 路径样式的目录总是相同的列表。路径没有什么异常,没有空格,名字只有a-z/A-Z,路径长度很短,最长路径包括文件名76个字符,基本路径34个字符。
如何强制 gcc 生成混合样式路径?
【问题讨论】:
-
你看过调用 GCC 时发出的实际命令吗?我的猜测是
-I指令是罪魁祸首。顺便说一句,您可能不需要进行此准备工作,GCC-MMD/-MD选项可以即时生成依赖项。 -
是的,
-I路径都是混合风格的路径,所以不是这样,很遗憾。我什至将$sourcePaths和$path包裹在cygpath -m中,但问题仍然存在。我将查看-MMD/-MD选项,但让它运行是我列表 atm 上的第一件事。
标签: c++ bash gcc makefile cygwin