【问题标题】:Why does output of fltk-config truncate arguments to gcc?为什么 fltk-config 的输出会截断 gcc 的参数?
【发布时间】:2010-05-31 20:37:25
【问题描述】:

我正在尝试构建一个我下载的应用程序,该应用程序使用 SCONS“make replacement”和 Fast Light Tool Kit Gui。

检测fltk存在的SConstruct代码是:

guienv = Environment(CPPFLAGS = '')
guiconf = Configure(guienv)

if not guiconf.CheckLibWithHeader('lo', 'lo/lo.h','c'):
    print 'Did not find liblo for OSC, exiting!'
    Exit(1)

if not guiconf.CheckLibWithHeader('fltk', 'FL/Fl.H','c++'):
    print 'Did not find FLTK for the gui, exiting!'
    Exit(1)

不幸的是,在我的(Gentoo Linux)系统和许多其他(Linux 发行版)上,如果包管理器允许同时安装 FLTK-1 和 FLTK-2,这可能会很麻烦。

我尝试修改 SConstruct 文件以使用 fltk-config --cflagsfltk-config --ldflags(或 fltk-config --libs 可能比 ldflags 更好),方法是像这样添加它们:

guienv.Append(CPPPATH = os.popen('fltk-config --cflags').read())
guienv.Append(LIBPATH = os.popen('fltk-config --ldflags').read())

但这会导致 liblo 的测试失败!查看config.log 显示它是如何失败的:

scons: Configure: Checking for C library lo...
gcc -o .sconf_temp/conftest_4.o -c "-I/usr/include/fltk-1.1 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT"
gcc: no input files
scons: Configure: no

这应该怎么做?

为了完成我的回答,如何从os.popen( 'command').read() 的结果中删除引号?

编辑这里真正的问题是为什么附加fltk-config 的输出会导致gcc 没有收到它应该编译的文件名参数?

【问题讨论】:

    标签: c++ python c scons fltk


    【解决方案1】:

    有两种类似的方法可以做到这一点: 1)

    conf = Configure(env)
    status, _ = conf.TryAction("fltk-config --cflags")
    if status:
      env.ParseConfig("fltk-config --cflags")
    else:
      print "Failed fltk"
    

    2)

      try:
        env.ParseConfig("fltk-config --cflags")
      except (OSError):
        print 'failed to run fltk-config you sure fltk is installed !?'
        sys.exit(1)
    

    【讨论】:

    • 天啊。有用。如果您将这些添加到测试上述两行是否成功的条件中,我将接受此作为正确答案。干杯。
    • 我已经尝试过了,它似乎可以工作:if not guienv.ParseConfig("fltk-config --cflags"): print 'failed to run fltk-config you sure fltk is installed !?' Exit(1)
    • 但我只是想确保这是正确的,因为我现在没有安装 没有 FLTK 的系统进行测试。
    • Imran,谢谢这些,我都试过了,但只成功地让第一个版本工作。
    【解决方案2】:

    这是一个相当复杂的问题,没有快速的答案

    我在http://www.scons.org/wiki/UsingPkgConfig 参考了使用pkg-config 和scons 的说明。下面的问题也有帮助 Test if executable exists in Python?.

    但我们需要在这些方面走得更远。

    所以经过大量调查后,我发现 os.popen('command').read() 不会修剪尾随换行符 '\n',这是导致发送给 GCC 的参数截断的原因。

    我们可以使用 str.rstrip() 来删除尾随的 '\n'。

    其次,正如config.log 所示,fltk-config 提供的参数在将它们提供给 GCC 之前用双引号括起来。我不确定具体细节,但这是因为fltk-config(通过os.popen)的输出包含空格字符。

    我们可以使用strarray = str.split(" ", str.count(" ")) 之类的东西将输出拆分为出现空格字符的子字符串。

    还值得注意的是,我们试图将 fltk-config --ldflags 附加到 GUI 环境中的错误变量,它们应该已添加到 LINKFLAGS

    不幸的是,这只是解决方案的一半。

    我们需要做的是:

    • 在系统上查找可执行文件的完整路径
    • 将参数传递给可执行文件并捕获其输出
    • 将输出转换为合适的格式以附加到CPPFLAGSLINKFLAGS

    所以我定义了一些函数来帮助...

    1) 在系统上查找可执行文件的完整路径: (见:Test if executable exists in Python?

    def ExecutablePath(program):
        def is_exe(fpath):
            return os.path.exists(fpath) and os.access(fpath, os.X_OK)
        fpath, fname = os.path.split(program)
        if fpath:
            if is_exe(program):
                return program
        else:
            for path in os.environ["PATH"].split(os.pathsep):
                exe_file = os.path.join(path, program)
                if is_exe(exe_file):
                    return exe_file
        return None
    

    1b) 我们还需要测试可执行文件是否存在:

    def CheckForExecutable(context, program):
        context.Message( 'Checking for program %s...' %program )
        if ExecutablePath(program):
            context.Result('yes')
        return program
        context.Result('no')
    

    2) 将参数传递给可执行文件并将输出放入数组中:

    def ExecutableOutputAsArray(program, args):
        pth = ExecutablePath(program)
        pargs = shlex.split('%s %s' %(pth, args))
        progout = subprocess.Popen( pargs , stdout=subprocess.PIPE).communicate()[0]
        flags = progout.rstrip()
        return flags.split(' ', flags.count(" "))
    

    一些用法:

    guienv.Append(CPPFLAGS =  ExecutableOutputAsArray('fltk-config', '--cflags') )
    guienv.Append(LINKFLAGS = ExecutableOutputAsArray('fltk-config', '--ldflags') )
    guienv.Append(LINKFLAGS = ExecutableOutputAsArray('pkg-config', '--libs liblo') )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-29
      • 2020-01-16
      • 1970-01-01
      相关资源
      最近更新 更多