Calling CheckLib from SConscript file - scons

I'm attempting to check for the existence of a library from inside my SConscript file, as follows:
# Not sure if this bit is relevant:
Import('env')
env = env.Clone()
# This is what I'm trying to do:
conf = env.Configure()
if conf.CheckLib('gcrypt'):
pass # actually something more interesting
...but it's not working. All I'm getting is an opaque error from scons, as follows:
scons: ***
File "/home/src/foo/bar/SConscript", line 49, in <module>
...where line 49 is the conf = env.Configure() line.
This is on Mac OS X, where I don't expect to find the library mentioned. How do I detect this in my SConscript file?

I tested this and it worked just fine. Maybe its a problem with how you're creating or passing the env. Here is my sample code in case it helps:
SConstruct
env = Environment()
env.SConscript('SConscript', exports='env', duplicate=0)
SConscript
Import('env')
env = env.Clone()
conf = env.Configure()
if conf.CheckLib('gcrypt'):
pass
And here is the result:
$ scons
scons: Reading SConscript files ...
Checking for C library gcrypt... no
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.

Related

Multiple-variant MSVS project fails in SCons

I am trying to set up visual studio projects with debug and release builds in a large SCons project. The manual proclaims
Multiple calls to MSVSProject with different variants are allowed; all variants will be added to the project file with their appropriate build targets and sources.
However, when I try to do this, I get the error that "Multiple ways to build the same target were specified".
Minimal example (SConstruct file)
import os
from SCons.Script import *
env = Environment()
for variant in ['debug', 'release']:
env.MSVSProject(
target = 'hello' + env['MSVSPROJECTSUFFIX'],
srcs = 'hello.cpp',
buildtarget = os.path.join(variant, 'hello.exe'),
variant = variant)
This gives the following output:
scons: Reading SConscript files ...
scons: warning: Two different environments were specified for target hello.vcxproj,
but they appear to have the same action: GenerateProject(target, source, env)
File "SConstruct", line 7, in <module>
scons: *** Multiple ways to build the same target were specified for: hello.vcxproj (from ['prj_inputs:"python.exe" -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, \'Lib\', \'site-packages\', \'scons-3.1.2\'), join(sys.prefix, \'scons-3.1.2\'), join(sys.prefix, \'Lib\', \'site-packages\', \'scons\'), join(sys.prefix, \'scons\') ] + sys.path; import SCons.Script; SCons.Script.main()" -C "." -f SConstructutf-8; ppdefs: incpath: "debug\\hello.exe" "debug" "hello.cpp "hello.vcxproj"'] and from ['prj_inputs:"python.exe" -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, \'Lib\', \'site-packages\', \'scons-3.1.2\'), join(sys.prefix, \'scons-3.1.2\'), join(sys.prefix, \'Lib\', \'site-packages\', \'scons\'), join(sys.prefix, \'scons\') ] + sys.path; import SCons.Script; SCons.Script.main()" -C "." -f SConstructutf-8; ppdefs: incpath: "release\\hello.exe" "release" "hello.cpp "hello.vcxproj"'])
File "SConstruct", line 7, in <module>
Is this a bug in SCons, or am I not understanding how this is supposed to work?
I realize that the variants can be passed in a list as a single call, but maintaining seperate lists of sources and targets for different build types would not be possible without a major rewrite of the existing build infrastructure. I was hoping to use one environment per build type, and the quote from the manual makes it seem like SCons should be able to combine them into one MSVS project.
Any help would be greatly appreciated!
This is a bug in SCons, and has been submitted

SConscript EnvironmentError: No module named compilation_db

I'm trying to compile the GitHub project: https://github.com/commaai/openpilot, I'm getting an error when creating the SCons environment (the call to Environment()), it points this line :
Environement(
# Other options ...
tools=["default", "cython", "compilation_db"
)
The result of the scons is then :
scons: Reading SConscript files ...
EnvironmentError: No module named compilation_db:
File "/home/skoumad/openpilot/master/SConstruct", line 213:
"compilation_db"
File "/usr/lib/scons/SCons/Environment.py", line 982:
apply_tools(self, tools, toolpath)
File "/usr/lib/scons/SCons/Environment.py", line 107:
env.Tool(tool)
File "/usr/lib/scons/SCons/Environment.py", line 1788:
tool = SCons.Tool.Tool(tool, toolpath, **kw)
File "/usr/lib/scons/SCons/Tool/__init__.py", line 118:
module = self._tool_module()
File "/usr/lib/scons/SCons/Tool/__init__.py", line 215:
raise SCons.Errors.EnvironmentError(error_string)
I tried to install compilation_db using : https://pypi.org/project/scons-compiledb/0.4.7/
but still the same error :/.
Any idea on how to install this missing module ??
Regards.
You likely have a version of SCons older than 4.0.0
The compilation_db tool was added in 4.0.0
See release notice
If you're distro(linux,python, macports, etc) doesn't have 4.0.0 or newer, then I'd advise setting up a python virtualenv (no this is not a VM, it's just a tool to create a clean python environment to install packages in)
Here's how to do that:
# assuming posix system, for win32, of course change the path to windows correct syntax
# also the python below should be 3.5 or newer, generally it's best to use the newest installed
python -m venv ~/sconsvenv
. ~/sconsvenv/bin/activate
pip install scons
scons --version
# should yield
SCons by Steven Knight et al.:
SCons: v4.1.0.post1.dc58c175da659d6c0bb3e049ba56fb42e77546cd, 2021-01-20 04:32:28, by bdbaddog on ProDog2020
SCons path: ['/Users/bdbaddog/sconsvenv/lib/python3.8/site-packages/SCons']
Copyright (c) 2001 - 2021 The SCons Foundation

Compiling multiple files to exe

I got multiple files to compile to a standalone exe using cython.
compile.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("TheMainFile", ["TheMainFile.py"]),
Extension("HelperClass", ["HelperClass.py"]),
Extension("HelperClass2", ["HelperClass2.py"]),
]
setup(
name = 'Main',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
The main file that should be run by the exe is TheMainFile
running the following command
python .\compiler.py build_ext --inplace
creates 3 .c files, in the build dir however is no .exe, just .lib,.exp and .obj files.
Manually adding these files to a VS Projects to build, results in the following error
"Python.h": No such file or directory
Adding the following files to the project from C:\Python\include lastly results in "structmember.h": No such file or directory
My question is:
How do I compile these files to a binary where TheMainFile is executed.

Import error undefined symbol (C++ module in python) ZTINSt8ios_base7failureB5cxx11E

I know there are lots of similar questions on the website but I couldn't find an answer to my problem.
I'm wrapping C++ classes with Cython in order to use them with Python3. After building the external module with a setup.py, when I run the python program I got the following error:
from "name of.pyx file" import "name of the class to import"
Import error: /home/.../filename.so: undefined symbol: _ZTINSt8ios_base7failureB5cxx11E.
I'm on Ubuntu 16.04, I build the extensions from the terminal with the command line python3 setup.py build_ext --inplace, and then run the .py from the terminal or from Spyder in Anaconda (I got the error in both cases.)
From what I read the error might come from the cython compilation because i'm not linking some libraries. Is this true? If it is, could someone explain me how to do it?
I let you here my setup.py, in comments all the different setups I tried.
setup.py
from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy
#setup(ext_modules = cythonize(
#"pycoralv1.pyx", # our Cython source
#sources=["coralv1cpp.cpp"], # additional source file(s)
#language="c++", # generate C++ code
#))
#setup(ext_modules = cythonize(Extension(
# "pyCoralv1", # the extension name
# sources=["pyCoralv1.pyx", "Coralv1cpp.cpp"], # the Cython source and
# additional C++ source files
# language="c++", # generate and compile C++ code
# )))
#setup(
# name = "testcoral",
# ext_modules = cythonize('*.pyx'),
#)
ext_modules = [
Extension(
"pyCoralv1",
sources=["pyCoralv1.pyx", "Coralv1cpp.cpp"],
extra_compile_args=['-fopenmp',"-fPIC"],
extra_link_args=['-fopenmp',"-I", "/usr/include/glib-2.0", "-l", "glib-2.0", "-I", "/usr/lib/x86_64-linux-gnu/glib-2.0/include"],
language="c++",
)
]
for e in ext_modules:
e.pyrex_directives = {"boundscheck": False}
setup(
name='Coral library',
ext_modules=cythonize(ext_modules),
include_dirs = [numpy.get_include()]
)
The problem was solved after installing libgcc in anaconda: conda install libgcc, there was a missing library.

SCons: How to import a Python module in an SConscript which has been invoked with VariantDir?

My build is structured like:
SConstruct
subdir/SConscript
subdir/module/__init__.py
SConstruct invokes subdir/SConscript as a subsidiary:
# SConstruct
SConscript('subdir/SConscript')
subdir/SConscript imports module:
# subdir/SConscript
from module import foo
do SConsy stuff with foo()...
This works fine until I use variant_dir with subdir/SConscript:
# SConstruct
SConscript('subdir/SConscript', variant_dir='subdir/build', duplicate=0)
The problem is that the import fails because module is no longer in the path, which has been altered by variant_dir.
Is there a standard way to solve this problem in either SCons or Python? I know about the special site_scons directory, but it appears that this directory must exist at the top level with the root SConstruct, and I'd like to keep subdir-specific files under subdir.
Use site_scons dir in project root dir for you module. For example i've module xxx, and he is placed : root/site_scons/xxx/__init__.py. Now, i can import xxx in all of my SConscript files.
In the SConscript, before the import, alter Python's path:
# subdir/SConscript
module_path = Dir('.').srcnode().abspath # get the path to subdir
import sys
sys.path.append(module_path)
from module import foo
export PYTHONPATH=/path/to/dir_of_modules
This worked for me

Resources