为什么 fltk-config 的输出会截断 gcc 的参数?

发布于 2024-09-03 14:35:36 字数 1345 浏览 1 评论 0 原文

我正在尝试构建一个我下载的应用程序,它使用 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 code> 可能比 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无法接收它应该编译的文件名参数?

I'm trying to build an application I've downloaded which uses the SCONS "make replacement" and the Fast Light Tool Kit Gui.

The SConstruct code to detect the presence of fltk is:

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)

Unfortunately, on my (Gentoo Linux) system, and many others (Linux distributions) this can be quite troublesome if the package manager allows the simultaneous install of FLTK-1 and FLTK-2.

I have attempted to modify the SConstruct file to use fltk-config --cflags and fltk-config --ldflags (or fltk-config --libs might be better than ldflags) by adding them like so:

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

But this causes the test for liblo to fail! Looking in config.log shows how it failed:

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

How should this really be done?

And to complete my answer, how do I remove the quotes from the result of os.popen( 'command').read()?

EDIT The real question here is why does appending the output of fltk-config cause gcc to not receive the filename argument it is supposed to compile?

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

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

发布评论

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

评论(2

蓝天 2024-09-10 14:35:36

有 2 种类似的方法可以做到这一点:
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)

There are 2 similar ways to do this:
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)
携余温的黄昏 2024-09-10 14:35:36

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

我已经参考了 pkg-config 与 scons 的说明rel="nofollow noreferrer">http://www.scons.org/wiki/UsingPkgConfig。下面的问题也很有帮助
测试 Python 中是否存在可执行文件?

但我们需要在这些方面更进一步。

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

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

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

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

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

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

我们需要做的是:

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

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

1)查找系统上可执行文件的完整路径:
(请参阅:测试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') )

This is quite a complex problem with no quick answer

I have referred to the instructions for using pkg-config with scons at http://www.scons.org/wiki/UsingPkgConfig. The following question is also helpful
Test if executable exists in Python?.

But we need to go a little bit further with these.

So after much investigation I discovered os.popen('command').read() does not trim the trailing newline '\n' which is what caused the truncation of the arguments sent to GCC.

We can use str.rstrip() to remove the trailing '\n'.

Secondly, as config.log shows, the arguments which fltk-config provides, SCONS wraps up in double quotes before giving them to GCC. I'm not exactly sure of the specifics but this is because the output of fltk-config (via os.popen) contains space characters.

We can use something like strarray = str.split(" ", str.count(" ")) to split the output into substrings where the space characters occur.

It is also worth noting that we were attempting to append the fltk-config --ldflags to the wrong variable within the GUI environment, they should have been added to LINKFLAGS.

Unfortunately this is only half way to the solution.

What we need to do is:

  • Find the full path of an executable on the system
  • Pass arguments to an executable and capture its output
  • Convert the output into a suitable format to append to the CPPFLAGS and LINKFLAGS.

So I have defined some functions to help...

1) Find full path of executable on system:
( see: 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) We also need to test for executable existence:

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

2) Pass arguments to executable and place the output into an array:

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(" "))

Some usage:

guienv.Append(CPPFLAGS =  ExecutableOutputAsArray('fltk-config', '--cflags') )
guienv.Append(LINKFLAGS = ExecutableOutputAsArray('fltk-config', '--ldflags') )
guienv.Append(LINKFLAGS = ExecutableOutputAsArray('pkg-config', '--libs liblo') )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文