def ManualExclude ( mb ):
    global_ns = mb.global_ns
    if MAIN_NAMESPACE:
        main_ns = global_ns.namespace( MAIN_NAMESPACE )
    else:
        main_ns = global_ns
    excludes=["::OIS::JoyStickState::mVectors"]
    for e in excludes:
        main_ns.variable(e).exclude()
    if environment.isMac():
        print dir ( main_ns.class_('::OIS::JoyStick'))
        for c in main_ns.classes():
            if not c.exportable:
                print "Excluding Class", c
###                c.exclude()
#            if c.access_type != 'public':
#                c.exclude()
  #          if 'JoyStick' in c.name:
  #              print "excluding:", c
  #              c.exclude()#
        for c in main_ns.member_functions():
            if not c.exportable or c.access_type == 'private':
                print "Excuding func", c
 ###               c.exclude()
 ##           if 'JoyStick' in c.name:
 #               print "excluding:", c
 #               c.exclude()
        for c in main_ns.variables():
            if c.access_type != 'public':
                print "Excluding var:", c
def generate_ogrenewt():
 
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.ogrenewt.root_dir, "python_ogrenewt.h" )
                        , environment.ogrenewt.cache_file )
                        
    defined_symbols = [ 'OGRE_NONCLIENT_BUILD','__PYTHONOGRE_BUILD_CODE',
                        'ogrenewt_NONCLIENT_BUILD','OIS_NONCLIENT_BUILD' ] #, 'OIS_STATIC_BUILD' ]
    defined_symbols.append( 'VERSION_' + environment.ogrenewt.version )
      
    if environment._USE_THREADS:
        defined_symbols.append('BOOST_HAS_THREADS')
        defined_symbols.append('BOOST_HAS_WINTHREADS')
    if environment.isLinux():
        defined_symbols.append('BOOST_IS_ENUM')

    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.ogrenewt.include_dirs
                                          , define_symbols=defined_symbols
                                          , cflags=environment.ogrenewt.cflags
                                          , indexing_suite_version=2 )

    ## This module depends on Ogre
    mb.register_module_dependency ( environment.ogre.generated_dir )
    filter_declarations (mb)
    #
    # fix shared Ptr's that are defined as references but NOT const...
    #
    find_nonconst ( mb.namespace( 'Ogre' ) )

    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True

    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )
    
    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    set_call_policies ( mb.global_ns.namespace ('OgreNewt') )
    
    # here we fixup functions that expect to modifiy their 'passed' variables  
    #  
    add_transformations ( mb )
    
    
    # 
    # now add properties
    #
    for cls in mb.namespace ('OgreNewt').classes():
        cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t()  )
        common_utils.add_LeadingLowerProperties ( cls )
    
    ## add additional version information to the module to help identify it correctly 
    common_utils.addDetailVersion ( mb, environment, environment.ogrenewt )

    # create the doc extractor we'll be using
    extractor = exdoc.doc_extractor("")
    #
    #Creating the actual code. After this step you should not modify/customize declarations.
    #
    mb.build_code_creator (module_name='_ogrenewt_', doc_extractor= extractor)
    for incs in environment.ogrenewt.include_dirs:
        mb.code_creator.user_defined_directories.append( incs )
    mb.code_creator.replace_included_headers( customization_data.header_files(environment.ogrenewt.version) )

    huge_classes = map( mb.class_, customization_data.huge_classes(environment.ogrenewt.version) )

    mb.split_module(environment.ogrenewt.generated_dir, huge_classes)

#     return_pointee_value_source_path \
#         = os.path.join( environment.pyplusplus_install_dir
#                         , 'pyplusplus_dev'
#                         , 'pyplusplus'
#                         , 'code_repository' )
#                         ## , 'return_pointee_value.hpp' ) ## Removed AJM 1/1/07

#     return_pointee_value_target_path \
#         = os.path.join( environment.ogrenewt.generated_dir, 'return_pointee_value.hpp' )

#     if not os.path.exists( return_pointee_value_target_path ):
#         shutil.copy( return_pointee_value_source_path, environment.ogrenewt.generated_dir )

    if environment.isMac():
       ## now we need to ensure a series of headers and additional source files are
      ## copied to the generated directory..
      basePath = os.path.join(environment.Config.PATH_OgreAddons,'ogrenewt', 'OgreNewt_Main')
      common_utils.copyTree ( sourcePath = os.path.join(basePath, 'inc'),
                              destPath = environment.ogrenewt.generated_dir, 
                              recursive= False,
                              extensions = ['h'] )
      common_utils.copyTree ( sourcePath = os.path.join(basePath, 'src'),
                              destPath = environment.ogrenewt.generated_dir, 
                              recursive= False,
                              collapse = True, # put all the source in a single directory
                              extensions = ['cpp'] )
def spawnTask ( task, cwdin = '', getoutput=None ):
    """Execute a command line task and manage the return code etc
    """
    global ENV_SET
    PREFIX = environment.PREFIX
    PATH = os.environ["PATH"]
    env = os.environ
    env["USESYSTEM"] = str(environment.UseSystem)
    if not ENV_SET: # this actually changes the environment so we shouldn't do it more than once
        env["PKG_CONFIG_PATH"]=os.path.join(PREFIX,"lib/pkgconfig")
        env["LD_LIBRARY_PATH"]=os.path.join(PREFIX,"lib")
        if environment.isMac():
            env["CFLAGS"]="-I"+PREFIX+"/include -L"+PREFIX+"/lib"
            env["CXXFLAGS"]="-I"+PREFIX+"/include -L"+PREFIX+"/lib"
            ##env["LDFLAGS"]="-Wl,-rpath='\$\$ORIGIN/../../lib' -Wl,-rpath='\$\$ORIGIN' -Wl,-z,origin"  ### Mac GCC 4.0.1 doesn't support rpath
            env["PYTHONPATH"]=PREFIX+"/lib/python"+environment.PythonVersionString+"/site-packages"
            env["CCFLAGS"]=" "+env["CFLAGS"]
        else:
            for FLAGS in "CFLAGS", "CXXFLAGS", "CCFLAGS", "LDFLAGS":
                if not FLAGS in env:
                    env[FLAGS] = ""
            if environment.isWindows():
                env["CFLAGS"]+=" "+"-I"+os.path.join(PREFIX,"include")
            else:
                env["CFLAGS"]+=" "+"-I"+os.path.join(PREFIX,"include")+ " -L"+os.path.join(PREFIX,"lib")
                if environment.is64():
                    env["CFLAGS"]+=" -L"+os.path.join(PREFIX,"lib64")

            if hasattr(environment, 'cxx_compiler'):
                env['CXX'] = environment.cxx_compiler
                # We need to tell gccxml about this change
                if not hasattr(environment, 'gccxml_compiler'):
                  env['GCCXML_COMPILER'] = environment.cxx_compiler
            if hasattr(environment, 'cc_compiler'):
                env['CC'] = environment.cc_compiler
            if hasattr(environment, 'gccxml_compiler'):
              _env['GCCXML_COMPILER'] = environment.cxx_compiler

            env["CXXFLAGS"]+=" "+env["CFLAGS"]
            env["CCFLAGS"]+=" "+env["CFLAGS"]
            env["LDFLAGS"]+="-Wl,-rpath='$$ORIGIN/../../lib' -Wl,-rpath='$$ORIGIN' -Wl,-z,origin"
            env["PYTHONPATH"]=PREFIX+"/lib/python"+environment.PythonVersionString+"/site-packages"
            if environment.is64():
                env["PYTHONPATH"]=env["PYTHONPATH"]+":"+PREFIX+"/lib64/python"+environment.PythonVersionString+"/site-packages"
            env["ZZIPLIB_LIBS"]="-lzzip"
        if environment.isWindows():
            ## Make sure the right python interpreter is in the path so scons gets called correctly...
            PATH_Python = os.path.dirname( sys.executable )
            env["PATH"]=PATH_Python+';'+PREFIX+"\\bin;" + PATH
        else: 
            env["PATH"]=PREFIX+"/bin:" + PATH
        ENV_SET=True

    logger.debug ( "Spawning '%s' in '%s'" % (task,cwdin) )

    if VERBOSE:
        out, err = "", ""
        process = subprocess.Popen (task, shell=True, cwd = cwdin, env=env)
        returncode = process.wait()
    else:
        process = subprocess.Popen (task, shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd = cwdin, env=env)
        try:
            out,err = process.communicate()
            returncode = process.returncode
        except:
            returncode = -1

    if getoutput is not None:
        if returncode != -1:
            getoutput.write(out)
            getoutput.write(err)

    if returncode != 0:
        logger.warning ( "Task Failed" )
        logger.debug ( out )
        logger.debug ( err )
    elif FULL_LOGGING:
        logger.warning ( "Full Logging ON" )
        logger.debug ( out )
        logger.debug ( err )

    if returncode != 0 and FAILHARD:
        exit(" The following command failed %s" % task)
    return returncode
def generate_code():
    messages.disable(
#           Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X
          messages.W1020
        , messages.W1021
        , messages.W1022
        , messages.W1023
        , messages.W1024
        , messages.W1025
        , messages.W1026
        , messages.W1027
        , messages.W1028
        , messages.W1029
        , messages.W1030
        , messages.W1031
        , messages.W1035
        , messages.W1040
        , messages.W1038
        , messages.W1041
#         , messages.W1036 # pointer to Python immutable member
#         , messages.W1033 # unnamed variables
#         , messages.W1018 # expose unnamed classes
#         , messages.W1049 # returns reference to local variable
#         , messages.W1014 # unsupported '=' operator
         )
    #
    # Use GCCXML to create the controlling XML file.
    # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded
    # NOTE: If you update the source library code you need to manually delete the cache .XML file
    #
    xml_cached_fc = parser.create_cached_source_fc(
                        os.path.join( environment.ois.root_dir, "python_ois.h" )
                        , environment.ois.cache_file )

    defined_symbols = ['OIS_NONCLIENT_BUILD' ]
    defined_symbols.append( 'VERSION_' + environment.ois.version )
    if environment.isMac():
        defined_symbols.append ('OIS_APPLE_PLATFORM')
    #
    # build the core Py++ system from the GCCXML created source
    #
    mb = module_builder.module_builder_t( [ xml_cached_fc ]
                                          , gccxml_path=environment.gccxml_bin
                                          , working_directory=environment.root_dir
                                          , include_paths=environment.ois.include_dirs
                                          , define_symbols=defined_symbols
                                          , indexing_suite_version=2
                                          , cflags=environment.ois.cflags
                                           )

    # if this module depends on another set it here
    mb.register_module_dependency ( environment.ogre.generated_dir )

    # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off
    mb.constructors().allow_implicit_conversion = False

    mb.BOOST_PYTHON_MAX_ARITY = 25
    mb.classes().always_expose_using_scope = True

    #
    # We filter (both include and exclude) specific classes and functions that we want to wrap
    #
    global_ns = mb.global_ns
    global_ns.exclude()
    main_ns = global_ns.namespace( MAIN_NAMESPACE )
    main_ns.include()

    common_utils.AutoExclude ( mb, MAIN_NAMESPACE )
    ManualExclude ( mb )
    common_utils.AutoInclude ( mb, MAIN_NAMESPACE )
    ManualInclude ( mb )
    # here we fixup functions that expect to modifiy their 'passed' variables
    ManualTransformations ( mb )
    AutoFixes ( mb, MAIN_NAMESPACE )
    ManualFixes ( mb )
    common_utils.Auto_Functional_Transformation ( main_ns )

    #
    # We need to tell boost how to handle calling (and returning from) certain functions
    #
    common_utils.Set_DefaultCall_Policies ( mb.global_ns.namespace ( MAIN_NAMESPACE ) )

    #
    # the manual stuff all done here !!!
    #
    hand_made_wrappers.apply( mb )

    NoPropClasses = [""]
    for cls in main_ns.classes():
        if cls.name not in NoPropClasses:
            cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() )

    ## add additional version information to the module to help identify it correctly
    common_utils.addDetailVersion ( mb, environment, environment.ois )

    ##########################################################################################
    #
    # Creating the code. After this step you should not modify/customize declarations.
    #
    ##########################################################################################
    extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing
    mb.build_code_creator (module_name='_ois_' , doc_extractor= extractor )

    for inc in environment.ois.include_dirs:
        mb.code_creator.user_defined_directories.append(inc )
    mb.code_creator.user_defined_directories.append( environment.ois.generated_dir )

# # #     mb.code_creator.replace_included_headers( customization_data.header_files( environment.ois.version ) )
    ## we need to remove the previous one
    lastc = mb.code_creator.creators[ mb.code_creator.last_include_index() ]
    mb.code_creator.remove_creator( lastc )
    # and now add our precompiled ones..
    for x in range (len (customization_data.header_files( environment.ois.version ) ), 0 ,-1 ):
        h = customization_data.header_files( environment.ois.version )[x-1]
        mb.code_creator.adopt_creator ( include.include_t ( header= h ), 0)


    huge_classes = map( mb.class_, customization_data.huge_classes( environment.ois.version ) )

    mb.split_module(environment.ois.generated_dir, huge_classes, use_files_sum_repository=False)