【问题标题】:gcc -MM on cygwin: sometimes unix style pathscygwin 上的 gcc -MM:有时是 unix 风格的路径
【发布时间】: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


【解决方案1】:

我可以在我的项目中看到同样的问题。我在 Windows 上使用来自 Cygwin 的 gmake.exe

gcc -MM 的一次调用输出 Windows 样式路径 (C:/project/file.h) 和 Cygwin 样式路径 (/cygdrive/c/project/file.h)。

我还不知道如何解决这个问题,但我发现是什么触发了对 Cygwin 样式路径的更改。当包含使用相对路径时会发生这种情况。因此,当文件包含#include "../file.h" 时,gcc -MM 的输出将包含file.h 的绝对路径,使用 Cygwin 样式的路径。

【讨论】:

    猜你喜欢
    • 2011-02-08
    • 1970-01-01
    • 2015-07-18
    • 2017-07-17
    • 1970-01-01
    • 2010-11-27
    • 2014-08-10
    • 2014-08-10
    • 1970-01-01
    相关资源
    最近更新 更多