def fillDefaultVariants(self, varKeys): """ Fill the variants variable with default allowable settings. """ if "type" in varKeys: self.variants["type"] = [["debug","optimized"], True] if sca_util.GetPlatform() == "win32": self.variants["type"][0].append("debugrt") if "libtype" in varKeys: libtype_is_alternative = False # On Windows, SCons does not use the object file extension to # distinguish between object files compiled for static and dynamic # libraries. We help out by distinguishing the two by directory. if sca_util.GetPlatform() == "win32": libtype_is_alternative = True self.variants["libtype"] = [["shared","static"], libtype_is_alternative] if "arch" in varKeys: valid_archs = detectValidArchs() if len(valid_archs) == 0: valid_archs = ["default"] print "Valid archs: ", valid_archs self.variants["arch"] = [valid_archs[:], True] else: self.variants["arch"] = [["default"], True]
def _buildImpl(self): """ Sets up the build dependencies and the install. """ # Build rule prog = self.env.Program(self.fileNode, source = self.sources) self.targets = prog # Add executable to file bundle fb = self.package.createFileBundle() if sca_util.GetPlatform() == 'darwin' and self.isAppBundle: # create prefix beyond <prefix>/bin appBundlePre = pj(self.installPrefix, self.fileNode.rstr() + '.app', 'Contents') # install Info.plist fb.addFiles(self.infoPlist, appBundlePre, False) # install PkgInfo fb.addFiles(self.pkgInfo, appBundlePre, False) # install actual exectuable file fb.addFiles(prog, pj(appBundlePre,'MacOS') , False) # install resource files for res in self.resources: fb.addFiles(res, pj(appBundlePre,'Resources'), False) else: fb.addFiles(prog, self.installPrefix, False)
def setInitial(self, optDict): " Set initial values from given dict " if self.verbose: print " Setting initial %s settings." % self.moduleName if optDict.has_key(self.optionKey): self.fpcFile = optDict[self.optionKey] if self.verbose: print " %s specified or cached. [%s]." % (self.optionKey, self.fpcFile) self.flagpoll_parser = sca_util.FlagPollParser(self.moduleName, self.fpcFile) if not self.flagpoll_parser.valid: print "Option: %s Could not init flagpoll parser." % self.moduleName
def applyQtBuildFlags(env): env.AppendUnique(CPPDEFINES=['QT_ON']) if sca_util.GetPlatform() == 'darwin': env.Append(LINKFLAGS=[ '-framework', 'QtCore', '-framework', 'QtDesigner', '-framework', 'QtGui', '-framework', 'QtOpenGL', '-framework', 'QtScript', '-framework', 'QtSvg', '-framework', 'QtXml', '-framework', 'OpenGL' ]) env.AppendUnique(CXXFLAGS=[ '-F/Library/Frameworks/QtCore.framework', '-F/Library/Frameworks/QtDesigner.framework', '-F/Library/Frameworks/QtGui.framework', '-F/Library/Frameworks/QtOpenGL.framework', '-F/Library/Frameworks/QtScript.framework', '-F/Library/Frameworks/QtSvg.framework', '-F/Library/Frameworks/QtXml.framework' ]) else: print "Please use the flagpoll based method for compiling against Qt on Linux."
def check_lib(libname, lib_filename, extraLibs, env): """ Helper method that checks if we can compile code that uses capabilities from the boost library 'libname' and get the symbols from the library lib_filename. """ header_to_check = pj('boost', 'config.hpp') if self.headerMap.has_key(libname): header_to_check = self.headerMap[libname] # Create config environment # - Need to extend the environment conf_env = env.Clone() conf_env.Append(CPPPATH=self.found_incs, LIBPATH=self.found_lib_paths, LIBS=extraLibs, CPPDEFINES=self.found_defines) if "python" == libname: conf_env.Append( CPPPATH=self.python_inc_dir, LIBPATH=self.python_lib_path, LINKFLAGS=self.python_link_flags, #LIBS = [lib_filename] + self.python_extra_libs LIBS=self.python_extra_libs) # Thread library needs some additional libraries on Linux... (yuck) if "thread" == libname: conf_env.Append(LIBS=[lib_filename] + self.thread_extra_libs) platform = sca_util.GetPlatform() # We have to use the dynamic MSVC runtime in order to allow dynamic # linking of Boost libraries during this phase of testing. if self.preferDynamic and platform == "win32": conf_env.Append(CXXFLAGS=["/MD"]) conf_ctxt = Configure(conf_env) result = conf_ctxt.CheckLibWithHeader(lib_filename, header_to_check, "c++") conf_ctxt.Finish() return result
def applyPythonModEnv(self, env, useDebug=None, **kwds): """ Update the environment for building python modules kwds - Dictionary of customization flags use_visibility - if true, then try to use visibility flags on g++ """ if not "python" in self.lib_names: print "Tried to updatePythonModEnv with boost option object not configured with python library.\n" sys.exit(0) self.apply(env) if not self.autoLink or self.version_str < "1.34": env.AppendUnique(LIBS=[ self.getFullLibName("python", env, useDebug) ]) # Add on the boost python library env.AppendUnique(CPPPATH=[self.python_inc_dir], LINKFLAGS=self.python_link_flags, LIBPATH=self.python_lib_path, LIBS=self.python_extra_libs) platform = sca_util.GetPlatform() env["SHLIBPREFIX"] = "" # Clear the library prefix settings if platform == "win32": env["SHLIBSUFFIX"] = ".pyd" if platform == "linux": env['CXXCOM'] += " && objcopy --set-section-flags .debug_str=contents,debug $TARGET" env['SHCXXCOM'] += " && objcopy -v --set-section-flags .debug_str=contents,debug $TARGET $TARGET" # Add visibility flags for gcc 4.0 and greater # XXX: It seems that this may not work on Mac OS X. if platform != "darwin" and "g++" in env["CXX"] and kwds.get( "use_visibility", True): gcc_version = env["CXXVERSION"].split(".") if int(gcc_version[0]) >= 4: env.AppendUnique(CXXFLAGS=[ '-fvisibility=hidden', '-fvisibility-inlines-hidden' ])
def __init__(self, name, requiredVersion, useDebug=False, useMt=True, libs=[], required=True, useCppPath=False, toolset="auto", useVersion=False, preferDynamic=True, autoLink=False, allowLibNameFallbacks=True): """ name - The name to use for this option requiredVersion - The version of Boost required (ex: "1.30.0") useDebug - Should we use debug boost libraries [default: False] useMt - Should we use multi-threaded boost libs [default: True] libs - Boost libraries needed that are actually compiled (base library names. ex: python) required - Is the dependency required? (if so we exit on errors) useCppPath - If true, then include path is added to CPPPATH if not, then added to CPPFLAGS directly toolset - The toolset name to use (ex: "auto","gcc", "il") useVersion - Attempt to use version in the library naming. preferDynamic - If true, prefer linking against a dynamic library.in your opinion, should I be looking at boost or at pyopensg on this one? autoLink - If true and using msvc, then attempt to use boost's autolinking capabilies. allowLibNameFallbacks - If true, then we can fallback on less explicit names for libraries. """ help_text = [ "Base directory for Boost. include, and lib should be under this directory.", "Include directory for boost (if not under base)." ] self.baseDirKey = "BoostBaseDir" self.incDirKey = "BoostIncludeDir" SConsAddons.Options.PackageOption.__init__( self, name, [self.baseDirKey, self.incDirKey], help_text) self.requiredVersion = requiredVersion self.libVersionStr = None self.lib_names = libs self.required = required self.useCppPath = useCppPath self.toolset = toolset self.preferDynamic = preferDynamic self.autoLink = autoLink if sca_util.GetPlatform() != "win32": self.autoLink = False self.available = False # Track availability self.found_incs = [] self.found_incs_as_flags = "" # The includes as flags to add on command line self.found_lib_paths = [] self.found_libs = { } # Name of actual libraries found (with or without toolset, etc) self.found_defines = [] # configurable options self.baseDir = None self.incDir = None self.setupLibrarySettings() # Options for which libraries to use self.use_mt = useMt self.use_debug = useDebug self.use_ver = useVersion self.allowLibNameFallbacks = allowLibNameFallbacks
def find(self, env): """ If base dir was not specified, attempt to find boost using some very basic searches. """ # --- Determine toolset --- # if self.toolset == "auto": print " Boost, autofinding toolset... ", if env["CC"] == "gcc": if sca_util.GetPlatform() == 'darwin': self.toolset = "darwin" else: self.toolset = "gcc" elif env["CC"] == "cl" and env.has_key("MSVS"): ver = env["MSVS"]["VERSION"] if "7.0" == ver: self.toolset = "vc7" else: (major, minor) = ver.rstrip("Exp").split(".")[:2] self.toolset = "vc%s%s" % (major, minor) elif sca_util.GetPlatform() == 'darwin' and env['CC'] == 'cc': self.toolset = "darwin" else: self.checkRequired("Could not auto determine boost toolset.") return print " toolset: [%s]" % self.toolset # Quick exit if nothing to find if self.baseDir != None: return ver_header = None boost_header = pj("boost", "version.hpp") # Find boost/version.hpp print " searching for boost..." # May be able to use configure context here... directories_to_check = [ env.Dictionary().get("CPPPATH"), pj("/", "usr", "include"), pj("/", "usr", "local", "include") ] for d in directories_to_check: if None != d: ver_header = env.FindFile(boost_header, d) if ver_header: break if None == ver_header: self.checkRequired( " could not find boost header [%s] in paths: %s" % (boost_header, directories_to_check)) else: ver_header = str(ver_header) print " found at: %s\n" % ver_header # find base dir self.incDir = os.path.dirname(os.path.dirname(ver_header)) self.baseDir = os.path.dirname(self.incDir)
def _getLibNameGenerators(self, env): """ Constructs a list of callables that can be used to generate variants for a given Boost library name. This takes into account whether we can strip off parts of the name. @rtype: list of callables @return: A list of callable objects is returned to the caller. Each takes a single string parameter that is the basic name of the Boost library (such as "filesystem"). The string returned is a possible variant of that library based on factors including the Boost version and whether multi-threading should be used. """ def generateName(libname, variant): return "boost_" + libname + variant debug_ext = "-d" if sca_util.GetPlatform() == "win32": debug_ext = "-gd" # Hack for now assuming debug code and runtime toolset_part = "" threading_part = "" runtime_part = "" version_part = "" if self.use_ver and self.libVersionStr is not None: version_part = "-" + self.libVersionStr if self.use_mt: threading_part = "-mt" if sca_util.GetPlatform( ) == 'darwin' and self.version_int_list[1] >= 37: toolset_part = '-xgcc' + "".join(env["CXXVERSION"].split('.')[:2]) else: if self.toolset: toolset_part = "-" + self.toolset if self.use_debug: runtime_part = debug_ext elif env and env.has_key("variant") and env["variant"].has_key( "type"): var_type = env["variant"]["type"] if "debugrt" == var_type: runtime_part = debug_ext generators = [ lambda n: generateName( n, toolset_part + threading_part + runtime_part + version_part) ] if self.allowLibNameFallbacks: # Prefer multi-threaded variants. if threading_part: generators.append(lambda n: generateName( n, toolset_part + threading_part + runtime_part + version_part)) generators.append(lambda n: generateName( n, threading_part + runtime_part + version_part)) generators.append( lambda n: generateName(n, threading_part + runtime_part)) generators.append(lambda n: generateName( n, toolset_part + runtime_part + version_part)) generators.append( lambda n: generateName(n, runtime_part + version_part)) generators.append(lambda n: generateName(n, runtime_part)) return generators
def setupLibrarySettings(self): " Setup some default settings and data that will be used on this platform. " # Map from library name to header to check for self.headerMap = { 'program_options': 'boost/program_options.hpp', #'python':'boost/python.hpp', 'python': 'boost/python/enum.hpp', 'signals': 'boost/signal.hpp', 'thread': 'boost/thread.hpp', 'filesystem': 'boost/filesystem/path.hpp' } # Map for extra libs needed for config test self.extraEnvOptions = {} # --- Build up settings using distutils.sysconfig to get Python build options --- # # distutils.sysconfig.get_config_vars() try: self.python_version = distutils.sysconfig.get_python_version( ) # ex: '2.3' except: self.python_version = distutils.sysconfig.get_config_var( "VERSION") # ex: '2.3' self.python_inc_dir = distutils.sysconfig.get_python_inc() self._extraBoostLibs = [] if sca_util.GetPlatform() == "win32": self.python_embedded_link_flags = [] self.python_lib_path = [pj(sys.prefix, 'libs')] self.python_static_lib_path = ["" ] # There is no static lib on win32 lib_python_fname = 'python' + self.python_version.replace('.', '') self.python_extra_libs = [lib_python_fname] #self.python_link_flags = ["/NODEFAULTLIB:"+lib_python_fname+"_d"] self.python_link_flags = [] self.thread_extra_libs = [] else: # Link flags that may be needed on unix for the embedded case #self.python_embedded_link_flags = [distutils.sysconfig.get_config_var('LINKFORSHARED')] self.python_embedded_link_flags = \ distutils.sysconfig.get_config_var('LINKFORSHARED').split(' ') self.python_lib_path = \ [distutils.sysconfig.get_config_var('LIBDIR')] self.python_static_lib_path = self.python_lib_path self.python_link_flags = [] self.python_extra_libs = [] python_extra_libs = \ distutils.sysconfig.get_config_var('LIBS').split(' ') + \ distutils.sysconfig.get_config_var('LOCALMODLIBS').split(' ') for item in python_extra_libs: if item.startswith("-l"): self.python_extra_libs.append(item) else: self.python_link_flags.append(item) # TODO: Figure out a more portable way (ideally extracting this # information from distutils.sysconfig). if sca_util.GetPlatform() == 'darwin': self.python_link_flags = \ ['-F%s' % distutils.sysconfig.get_config_var('PYTHONFRAMEWORKPREFIX'), '-framework', 'Python'] + self.python_link_flags else: lib_python_fname = 'python' + self.python_version self.python_extra_libs.insert(0, lib_python_fname) self.thread_extra_libs = []
def apply(self, env, libs=['system'], optimize=None, useCppPath=False, buildType=None): """ Add environment options for building against vapor. lib: One of: base, system, glut, x, qt. optimize: If true use --opt option, if None, then try to autoset based on env["variant"]. It will default to False useCppPath: If true, then put the include paths into the CPPPATH variable. """ if buildType is not None: optimize = buildType == 'optimized' # Auto-set optimize if not optimize: if env.has_key("variant") and env["variant"].has_key("type"): var_type = env["variant"]["type"] optimize = ("debug" != "var_type") else: optimize = False # Default to debug #if not (type(libs) in (types.TupleType, types.ListType)): # libs = (libs,) if not isinstance(libs, list): libs = [ libs, ] # Ensure we are using standardized naming naming_map = { ("base", "Base"): "Base", ("system", "System"): "System", ("GLUT", "glut", "Glut"): "GLUT", ("X", "x"): "X", ("QT", "qt"): "QT", ("contrib", "Contrib"): "Contrib" } for i in range(len(libs)): for (name_list, norm_name) in naming_map.iteritems(): if libs[i] in name_list: libs[i] = norm_name lib_names_str = " ".join( libs) # List of library names as a string for osg-config #print "lib_names_str: ", lib_names_str if self.osgconfig_cmd: # Returns lists of the options we want opt_option = " --dbg" if optimize: opt_option = " --opt" # Call script for output cflags_stripped = os.popen(self.osgconfig_cmd + opt_option + " --cflags " + lib_names_str).read().strip() libs_stripped = os.popen(self.osgconfig_cmd + " --libs " + lib_names_str).read().strip() # Get output from osg-config # Res that when matched against osg-config output should match the options we want # In future could try to use INCPREFIX and other platform neutral stuff inc_re = re.compile(r'(?: |^)-I(\S*)', re.MULTILINE) lib_re = re.compile(r'(?: |^)-l(\S*)', re.MULTILINE) lib_path_re = re.compile(r'(?: |^)-L(\S*)', re.MULTILINE) link_from_lib_re = re.compile(r'((?: |^)-[^lL]\S*)', re.MULTILINE) defines_re = re.compile(r'(?: |^)-D(\S*)', re.MULTILINE) optimization_opts_re = re.compile(r'^-(g|O\d)$') # Extract the flags and options from the script output found_cflags = cflags_stripped.split(" ") found_cflags = [ s for s in found_cflags if not optimization_opts_re.match(s) ] found_cflags = [s for s in found_cflags if not inc_re.match(s)] found_cflags = [s for s in found_cflags if not defines_re.match(s)] found_libs = lib_re.findall(libs_stripped) found_lib_paths = lib_path_re.findall(libs_stripped) found_defines = defines_re.findall(cflags_stripped) found_incs = inc_re.findall(cflags_stripped) found_incs_as_flags = [env["INCPREFIX"] + p for p in found_incs] #print "cflags_stripped: [%s]"%cflags_stripped #print "found cflags:", found_cflags #print "Found: ", found_defines #print "found_incs_as_flags: ", found_incs_as_flags #print "Found incs:", found_incs if len(found_cflags): env.Append(CXXFLAGS=found_cflags) if len(found_libs): env.Append(LIBS=found_libs) else: print "ERROR: Could not find OpenSG libs for libs:%s lib_names_str:%s" % ( libs, lib_names_str) if len(found_lib_paths): env.Append(LIBPATH=found_lib_paths) else: print "ERROR: Could not find OpenSG lib paths for libs: %s lib_names_str:%s" % ( libs, lib_names_str) if len(found_incs): if self.useCppPath or useCppPath: env.Append(CPPPATH=found_incs) else: env.Append(CXXFLAGS=found_incs_as_flags) if len(found_defines): env.Append(CPPDEFINES=found_defines) # If on Windows, just make some very lame assumptions and hope they are correct elif sca_util.GetPlatform() == "win32": lib_map = { "Base": [ "OSGBase", ], "GLUT": ["OSGWindowGLUT", "OSGSystem", "OSGBase"], "FileIO": [ "OSGFileIO", ], "Drawable": [ "OSGDrawable", ], "Group": [ "OSGGroup", ], "ImageFileIO": [ "OSGImageFileIO", ], "RenderTraversal": [ "OSGRenderTraversal", ], "State": [ "OSGState", ], "System": ["OSGSystem", "OSGBase"], "Text": [ "OSGText", ], "Util": [ "OSGUtil", ], "WIN32": [ "OSGWindowWIN32", ], "Window": [ "OSGWindow", ], "Contrib": ["OSGContrib", "OSGSystem", "OSGBase"] } found_libs = [] lib_suffix = "" if not optimize: lib_suffix = "D" for l in libs: #print "Checking: ", l #print "has_key: ", lib_map.has_key(l) if lib_map.has_key(l): found_libs.extend([lib + lib_suffix for lib in lib_map[l]]) lib_path = pj(self.baseDir, 'lib') inc_path = pj(self.baseDir, 'include') if not os.path.exists(lib_path): print "ERROR: Could not find OpenSG lib path. tried: ", lib_path if not os.path.exists(inc_path): print "ERROR: Could not find OpenSG include path. tried: ", inc_path env.AppendUnique(LIBS=found_libs, LIBPATH=[ lib_path, ], CPPPATH=[ inc_path, ]) # XXX: Hack to apply extra info that I would like to get from osg-config # if it only worked without cygwin common_cppdefines = [ "WIN32", "_WINDOWS", "WINVER=0x0400", ("_WIN32_WINDOWS", "0x0410"), ("_WIN32_WINNT", "0x0400"), "_OSG_HAVE_CONFIGURED_H_", "OSG_BUILD_DLL", "OSG_WITH_TIF", "OSG_WITH_JPG", "OSG_WITH_PNG", "OSG_WITH_GIF" ] debug_cppdefines = ["OSG_DEBUG"] glut_cppdefines = [ "OSG_WITH_GLUT", ] common_libs = [ "tif32", "libjpeg", "libpng", "opengl32", "glu32", "gdi32", "user32", "kernel32", "winmm", "wsock32" ] env.Append(CPPDEFINES=common_cppdefines, LIBS=common_libs) if not optimize: env.Append(CPPDEFINES=debug_cppdefines) if "GLUT" in libs: env.Append(CPPDEFINES=glut_cppdefines) #print "---------------------\nApplying OpenSG:\n-----------------" #print "lib_map: ", lib_map #print "libs: ", libs #print "found libs: ", found_libs #print "----------------------------------" # Apply dep dir settings if we have them #print "apply: depDir: ", self.depDir if self.depDir: #print "Apply: Have depdir:", self.depDir env.Append(CPPPATH=[ pj(self.depDir, 'include'), ], LIBPATH=[ pj(self.depDir, 'lib'), ])