def validate(self):
     """
     Attempt to validate the configuration of this toolchain. It checks for
     1) cross-compiler binaries in the PATH.
     2) the existence of the sysroot (though no guarantee it is the sysroot).
     3) a small program can be compiled.
     """
     if ( platform.system == 'Windows' ):
         toolchain_gcc = self.name + "-gcc.exe"
         toolchain_gpp = self.name + "-g++.exe"
     else:
         toolchain_gcc = self.name + "-gcc"
         toolchain_gpp = self.name + "-g++"
     toolchain_gcc_found = False 
     toolchain_gpp_found = False 
     path = os.environ['PATH']
     paths = path.split(os.pathsep)
     for dir in paths:
         if ( os.path.isdir(dir) ):
             pathname = os.path.join(dir,toolchain_gcc)
             if ( os.path.isfile(pathname) ):
                 toolchain_gcc_pathname = pathname
                 toolchain_gcc_found = True
             pathname = os.path.join(dir,toolchain_gpp)
             if ( os.path.isfile(pathname) ):
                 toolchain_gpp_pathname = pathname
                 toolchain_gpp_found = True
     if ( ( not toolchain_gcc_found ) or ( not toolchain_gpp_found ) ):
         print core.red_string("Cross-compiler binaries not found.")
         return 1
     print
     print "  Compilers validated: "
     print "    gcc : " + toolchain_gcc_pathname
     print "    gpp : " + toolchain_gpp_pathname
def show_current_build_mode():
    pretext = core.bold_string("Current build mode: ")
    found = False
    if os.path.exists(core.rosconfig_cmake()):
        for line in fileinput.input(core.rosconfig_cmake(),mode='r'):
            if (line.find("set(ROS_BUILD_TYPE Debug") != -1):
                sys.stdout.write(pretext + "Debug\n")
                found = True
                break
            elif (line.find("set(ROS_BUILD_TYPE Release") != -1):
                sys.stdout.write(pretext + "Release\n")
                found = True
                break
            elif (line.find("set(ROS_BUILD_TYPE RelWithDebInfo") != -1):
                sys.stdout.write(pretext + "RelWithDebInfo\n")
                found = True
                break
            elif (line.find("set(ROS_BUILD_TYPE MinSizeRel") != -1):
                sys.stdout.write(pretext + "MinSizeRel\n")
                found = True
                break
        if not found:
            print core.red_string("Unknown") + "(please check ROS_ROOT/rosconfig.cmake for problems)."
    else:
        print pretext + "RelWithDebInfo"
def select_toolchain_by_id(id):
    '''
    Selects toolchain by id.
      - return 1 if failure, 0 if success
    '''
    toolchains = toolchain_list()
    if ( int(id) > len(toolchains) ):
        print core.red_string("-- Aborting, # does not correspond to a toolchain.")
        list_toolchains()
        return 1
    else:
        selected_toolchain = toolchains[int(id)-1] # indexing starts at zero
        shutil.copyfile(selected_toolchain.pathname,core.rostoolchain_cmake())
        return 0
def delete_platform():
    '''
    Interactively deletes a user-defined platform.
      - return 1 if failure, 0 if success
    '''
    list_user_platforms()
    print
    platform_id_string = raw_input("Enter a platform id #: ")
    print
    if ( not platform_id_string.isdigit() ):
        print core.red_string("-- Aborting, invalid id #.")
        return 1
    platform_id = int(platform_id_string)
    platforms = platform_list()
    if not platform_id <= len(platforms):
        print core.red_string("-- Aborting, invalid id #.")
        return 1
    found_platform = False
    for platform in platforms:
        if ( platform.id == platform_id ):
            if ( platform.group == 'user' ):
                found_platform = True
                selected_platform = platform
    if ( not found_platform ):
        print core.red_string("-- Aborting, invalid id #.") # probably passed an eros platform id
        return 1
    else:
        os.remove(selected_platform.pathname)
        return 0
def select_platform():
    '''
    Interactively selects and sets an ros platform.
      - return 1 if failure, 0 if success
    '''
    list_platforms()
    platform_id_string = raw_input("Enter a platform id #: ")
    if ( not platform_id_string.isdigit() ):
        print core.red_string("Aborting, invalid id #.")
        return 1
    platform_id = int(platform_id_string)
    platforms = platform_list()
    if not platform_id <= len(platforms):
        print core.red_string("Aborting, invalid id #.")
        return 1
    found_platform = False
    for platform in platforms:
        if ( platform.id == platform_id ):
            found_platform = True
            selected_platform = platform
            break
    if ( not found_platform ):
        print core.red_string("Aborting, platform not found.")
        return 1
    else:
        set_platform(selected_platform)
        return 0
def delete_toolchain():
    '''
    Interactively deletes a user-defined toolchain.
      - return 1 if failure, 0 if success
    '''
    list_user_toolchains()
    print
    toolchain_id_string = raw_input("Enter a toolchain id #: ")
    if ( not toolchain_id_string.isdigit() ):
        print core.red_string("Aborting, invalid id #.")
        return 1
    toolchain_id = int(toolchain_id_string)
    toolchains = toolchain_list()
    if not toolchain_id <= len(toolchains):
        print core.red_string("Aborting, invalid id #.")
        return 1
    found_toolchain = False
    for toolchain in toolchains:
        if ( toolchain.id == toolchain_id ):
            if ( toolchain.group == 'user' ):
                found_toolchain = True
                selected_toolchain = toolchain
    if ( not found_toolchain ):
        print core.red_string("Aborting, invalid id #.") # probably passed an eros toolchain id
        return 1
    else:
        os.remove(selected_toolchain.pathname)
        return 0
def select_toolchain():
    '''
    Interactively selects and sets an ros toolchain.
      - return true or false depending on success/failure.
    '''
    list_toolchains()
    toolchain_id_string = raw_input("Enter a toolchain id #: ")
    if ( not toolchain_id_string.isdigit() ):
        print core.red_string("Aborting, invalid id #.")
        return False
    toolchain_id = int(toolchain_id_string)
    toolchains = toolchain_list()
    if not toolchain_id <= len(toolchains):
        print core.red_string("Aborting, invalid id #.")
        return False
    found_toolchain = False
    for toolchain in toolchains:
        if ( toolchain.id == toolchain_id ):
            found_toolchain = True
            selected_toolchain = toolchain
            break
    if ( not found_toolchain ):
        print core.red_string("Aborting, toolchain not found.")
        return False
    else:
        shutil.copyfile(selected_toolchain.pathname,core.rostoolchain_cmake())
        print
        return True
def select_toolchain_by_name(id_string):
    '''
    Selects toolchain by name or family/name string.
      - return 1 if failure, 0 if success
    '''
    bits = os.path.split(id_string)
    #print bits
    if  len(bits) == 2 :
        family = bits[0] # if just name is given, this will be empty
        name = bits[1]
        found_toolchain = False
        toolchains = toolchain_list()
        if family == "": # try and just match name
            for toolchain in toolchains:
                if ( toolchain.name == name ):
                    if found_toolchain:
                        print
                        print core.red_string("Multiple matches, please provide a full id string.")
                        list_toolchains()
                        return 1
                    else:
                        found_toolchain = True
                        selected_toolchain = toolchain
        else: # try and match both family, name
            for toolchain in toolchains:
                if toolchain.family == family and toolchain.name == name:
                    found_toolchain = True
                    selected_toolchain = toolchain
                    break
        if ( not found_toolchain ):
            print
            print core.red_string("Aborting, toolchain not found.")
            list_toolchains()
            return 1
        else:
            shutil.copyfile(selected_toolchain.pathname,core.rostoolchain_cmake())
            return 0
    else:
        print
        print core.red_string("Aborting, toolchain not found.")
        list_toolchains()
        return 1
def select_platform_by_name(id_string):
    '''
    Selects platform by name or family/name string.
      - return 1 if failure, 0 if success
    '''
    bits = os.path.split(id_string)
    if  len(bits) == 2 :
        family = bits[0] # if just name is given, this will be empty
        name = bits[1]
        found_platform = False
        platforms = platform_list()
        if family == "": # try and just match name
            for platform in platforms:
                if ( platform.name == name ):
                    if found_platform:
                        print
                        print core.red_string("Multiple matches, please provide a full id string.")
                        list_platforms()
                        return 1
                    else:
                        found_platform = True
                        selected_platform = platform
        else: # try and match both family, name
            for platform in platforms:
                if platform.family == family and platform.name == name:
                    found_platform = True
                    selected_platform = platform
                    break
        if ( not found_platform ):
            print
            print core.red_string("Aborting, platform not found.")
            list_platforms()
            return 1
        else:
            set_platform(selected_platform)
            return 0
    else:
        print
        print core.red_string("Aborting, platform not found.")
        list_platforms()
        return 1
def validate_mode(mode):
    if (mode != "Debug" ) and ( mode != "Release" ) and ( mode != "RelWithDebInfo" ) and ( mode != "MinSizeRel" ):
        print_valid_modes()
        print(core.red_string(mode) + " is not a valid build mode type.")
        return False
    return True
def create_platform():
    '''
    Create a platform configuration.
    '''
    print
    print core.bold_string("  Creating a User-Defined Eros Platform Configuration")
    print
    print "This is an interactive assistant to help define a new eros style cmake platform"
    print "configuration. It will prompt you for a few custom strings and then save the"
    print "configured platform module in ROS_HOME/eros/platforms (~/.ros/eros/platforms on linux)."
    print "It can then be listed and selected in the same way as as a regular eros platform"
    print "configuration."
    print
    print core.bold_string("  Platform Family")
    print 
    print "  This is simply a convenience variable that helps sort platforms in the eros"
    print "  and user-defined libraries. Common examples include: intel, arm etc."
    print
    platform_family = raw_input('  Enter a string for the platform family [custom]: ')
    if ( platform_family == '' ):
        platform_family = 'custom'
    print
    print core.bold_string("  Platform Name")
    print 
    print "  This is unique identifier usually denoting the specific cpu that it represents"
    print "  and will be the name of the resulting cmake file. Common examples include: "
    print "  core2, arm1176jzf-s etc."
    print
    platform_name = raw_input('  Enter a string for the platform name [generic]: ')
    print
    print core.bold_string("  Platform Compile flags")
    print 
    print "  A string containing any extra compile flags to be used for this configuration."
    print "  e.g. '-march=core2 -sse4. This is in addition to the default ros flags."
    print 
    platform_compile_flags = raw_input('  Enter a string for the platform compile flags []: ')
    print
    print core.bold_string("  Platform Link flags")
    print 
    print "  A string containing any extra link flags to be used for this configuration."
    print "  e.g. '-Wl,--as-needed'. This is in addition to the default ros flags."
    print 
    platform_link_flags = raw_input('  Enter a string for the platform link flags []: ')
    
    platform_template = open(eros_platform_template()).read()
    platform_template = platform_template.replace('${platform_family}',platform_family)
    platform_template = platform_template.replace('${platform_name}',platform_name)
    platform_template = platform_template.replace('${platform_compile_flags}',platform_compile_flags)
    platform_template = platform_template.replace('${platform_link_flags}',platform_link_flags)
    #print platform_template
    user_defined_platform_pathname = os.path.join(user_platform_dir(),platform_family,platform_name+'.cmake')
    if ( os.path.exists(user_defined_platform_pathname) ):
        print core.red_string("  Aborting, this platform configuration already exists (use --delete to remove).")
        return 1
    if not os.path.exists( os.path.dirname(user_defined_platform_pathname) ): # Make sure the dir exists before we open for writing
        os.makedirs(os.path.dirname(user_defined_platform_pathname))
    f = open(user_defined_platform_pathname, 'w')
    f.write(platform_template)
    rosconfig_tail = open(eros_rosconfig_tail()).read()
    f.write(rosconfig_tail)
    f.close()
    print
    print core.bold_string("Platform Finalised")
    print "-- Family: %s" %platform_family
    print "-- Name: %s" %platform_name
    print "-- CFlags: %s" %platform_compile_flags
    print "-- LFlags: %s" %platform_link_flags
    print "-- File: %s" %user_defined_platform_pathname
    print
    check_install_prefix()
def list_user_platforms():
    platforms = platform_list()
    print
    print core.bold_string("User platforms:")
    print
    for platform in platforms:
        if ( platform.group == 'user' ):
            if ( platform.current ):
                print "  %d) %s%s%s%s" %(platform.id,platform.family,os.sep,platform.name,core.red_string("*"))
            else:
                print "  %d) %s%s%s" %(platform.id,platform.family,os.sep,platform.name)
def create_toolchain():
    '''
    Create a cross-compiler cmake configuration. Note: hardwired for gcc
    cross compiler configurations at this point in time - is there even a use
    case that is different right now?
    '''
    print
    print core.bold_string("  Creating a User-Defined Eros Toolchain")
    print
    print "This is an interactive assistant to help define a new eros style cmake toolchain."
    print "It will prompt you for a few custom strings and then save the configured toolchain"
    print "in ROS_HOME/eros/toolchains (~/.ros/eros/toolchains on linux platforms). It can then be"
    print "listed and selected in the same way as as a regular eros toolchain."
    print
    print core.bold_string("  Toolchain Family")
    print 
    print "  This is simply a convenience variable that helps sort toolchains in the eros"
    print "  and user-defined libraries. Common examples include: crossdev, ubuntu,"
    print "  openembedded, etc."
    print
    toolchain_family = raw_input('  Enter a string for the toolchain family [custom]: ')
    if ( toolchain_family == '' ):
        toolchain_family = 'custom'
    print
    print core.bold_string("  Toolchain Tuple")
    print 
    print "  This is essential so that cmake can find the gcc cross-compiler. The toolchain"
    print "  tuple should match the prefix to your toolchain's cross-compilers, e.g. if your"
    print "  cross-compiler is i686-pc-linux-gnu-gcc, then the tuple is i686-pc-linux-gnu."
    print "  Compilers need to be in your system's PATH."
    print
    toolchain_tuple = raw_input('  Enter a string for the toolchain tuple: ')
    print
    print core.bold_string("  Toolchain Sysroot")
    print 
    print "  This is the root directory from which system headers and libraries can be found."
    print "  e.g. if toolchain pthreads header is /usr/i686-pc-linux-gnu/usr/include/pthread.h"
    print "  then your sysroot would be /usr/i686-pc-linux-gnu."
    print 
    toolchain_sysroot_default = "/usr/" + toolchain_tuple
    toolchain_sysroot = raw_input("  Enter a string for the toolchain sysroot [" + toolchain_sysroot_default + "]: ")
    if ( toolchain_sysroot == ''):
        toolchain_sysroot = toolchain_sysroot_default
    print
    print core.bold_string("  Toolchain Install Prefix")
    print 
    print "  This is the where your headers and libraries will get installed."
    print "  e.g. if your toolchain sysroot is /usr/i686-pc-linux-gnu/ then typically"
    print "  your install prefix will be /usr/i686-pc-linux-gnu/usr"
    print 
    toolchain_install_prefix_default = toolchain_sysroot + "/usr/"
    toolchain_install_prefix = raw_input("  Enter a string for the toolchain install prefix [" + toolchain_install_prefix_default + "]: ")
    if ( toolchain_install_prefix == ''):
        toolchain_install_prefix = toolchain_install_prefix_default
    print
    
    toolchain_template = open(eros_toolchain_template()).read()
    toolchain_template = toolchain_template.replace('${toolchain_family}',toolchain_family)
    toolchain_template = toolchain_template.replace('${toolchain_tuple}',toolchain_tuple)
    toolchain_template = toolchain_template.replace('${toolchain_sysroot}',toolchain_sysroot)
    toolchain_template = toolchain_template.replace('${toolchain_install_prefix}',toolchain_install_prefix)
    #print toolchain_template
    user_defined_toolchain_pathname = os.path.join(user_toolchain_dir(),toolchain_family,toolchain_tuple+'.cmake')
    if ( os.path.exists(user_defined_toolchain_pathname) ):
        print core.red_string("  Aborting, this toolchain configuration already exists (use --delete to remove).")
        return 1
    if not os.path.exists( os.path.dirname(user_defined_toolchain_pathname) ): # Make sure the dir exists before we open for writing
        os.makedirs(os.path.dirname(user_defined_toolchain_pathname))
    f = open(user_defined_toolchain_pathname, 'w')
    f.write(toolchain_template)
    f.close()
    print core.bold_string("Toolchain Finalised")
    print
    print "-- Family: %s" %toolchain_family
    print "-- Tuple: %s" %toolchain_tuple
    print "-- Sysroot: %s" %toolchain_sysroot
    print "-- Install Prefix: %s" %toolchain_install_prefix
    print "-- File: %s" %user_defined_toolchain_pathname
    print
def list_user_toolchains():
    toolchains = toolchain_list()
    print
    print core.bold_string("User toolchains:")
    print
    for toolchain in toolchains:
        if ( toolchain.group == 'user' ):
            if ( toolchain.current ):
                print "  %d) %s%s%s%s" %(toolchain.id,toolchain.family,os.sep,toolchain.name,core.red_string("*"))
            else:
                print "  %d) %s%s%s" %(toolchain.id,toolchain.family,os.sep,toolchain.name)