我正在尝试构建一个我已下载的应用程序,该应用程序使用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 --cflags
和fltk-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无法接收它应该编译的文件名参数?
答案 0 :(得分:1)
我在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
提供的参数,SCONS在将它们提供给GCC之前用双引号括起来。我不确定具体细节,但这是因为fltk-config
(通过os.popen
)的输出包含空格字符。
我们可以使用strarray = str.split(" ", str.count(" "))
之类的东西将输出拆分为空格字符出现的子串。
值得注意的是,我们试图将fltk-config --ldflags
附加到GUI环境中的错误变量,它们应该已添加到LINKFLAGS
。
我们需要做的是:
CPPFLAGS
和LINKFLAGS
。 所以我已经定义了一些函数来帮助......
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') )
答案 1 :(得分: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)