Esempio n. 1
0
    def occam(self, cfg, args):
        tool = self.name
        #(input_files, output_file, flags) = parse_ld_args(args)
        (input_files, output_file, flags) = self.parse_args(args)
        print "ld input files: " + ' '.join(input_files)
        # TODO: this seems to have side effects, but since I'm duplicating
        #      stdin it shouldn't, right?
        cfg.log("%(in)s\n%(out)s\n%(fl)s\n",
                 { 'in' : input_files.__repr__()
                 , 'out' : output_file.__repr__()
                 , 'fl' : flags.__repr__() })

        if '-' in input_files:
#             num = os.dup(0)
#             fd = os.fdopen(num,'r')
#             cfg.log("compiling stdin\n%(msg)s", {'msg' : fd.read()})
#             fd.close()
             return 0 # IAM: Could also check that output is /dev/null

        if '/dev/null' == output_file:
            cfg.log("skipping output /dev/null", {})
            return 0

        if len(input_files) == 0:
            return 0
        elif '-Wl,--help' in flags:
            # this is just help
            return 0
        elif '-Wl,-shared' in flags:
            # LLVM doesn't do shared...
            return 0
        elif '-Wl,-r' in flags or '-Wl,-i' in flags or '-Wl,--relocatable' in flags:
            # this is essentially linking as a library
            if output_file is None:
                output_file = ld_default_o(input_files[0])
            retcode = toolchain.bundle(self.fixname(output_file), 
                                       map(self.fixinputname,input_files),
                                       [x for x in flags if x.startswith('-l')],
                                       [x[2:] for x in flags if x.startswith('-L')])
            return retcode
        else:
            if output_file is None:
                output_file = ld_default_o(input_files[0])
            retcode = toolchain.link(map(self.fixinputname,input_files),
                                     self.fixname(output_file),
                                     flags + ['-lc'], 
                                     save='%s_main.bc' % output_file,
                                     link=True)
            return retcode
    def occam(self, cfg, args):
        tool = self.name
        #(input_files, output_file, flags) = parse_gcc_args(args)
        (input_files, output_file, flags) = self.parse_args(args)
        # TODO: this seems to have side effects, but since I'm duplicating
        #      stdin it shouldn't, right?
        cfg.log("%(in)s\n%(out)s\n%(fl)s\n",
                 { 'in' : input_files.__repr__()
                 , 'out' : output_file.__repr__()
                 , 'fl' : flags.__repr__() })

        if '-' in input_files:
#             num = os.dup(0)
#             fd = os.fdopen(num,'r')
#             cfg.log("compiling stdin\n%(msg)s", {'msg' : fd.read()})
#             fd.close()
             return 0 # IAM: Could also check that output is /dev/null

        if '/dev/null' == output_file:
            cfg.log("skipping output /dev/null", {})
            return 0

        if not os.getenv('VERBOSE') is None:
            try:
#                logging.getLogger().info("SOURCE FILE = %s", open(input_files[0]).read())
#                logging.getLogger().info("confdefs.h = %s", open("confdefs.h").read())
                pass
            except:
                pass
        if len(input_files) == 0 or ('-print-libgcc-file-name' in args):
            return 0
        elif '--help' in args:
            # this is just help
            return 0
        elif tool == 'clang-cpp' or ('-E' in args and output_file is None):
            # this is just cpp
            return 0
        elif '-shared' in args:
            # LLVM doesn't do shared...
            return 0
        elif '-r' in args:
            # this is essentially linking
            if output_file is None:
                output_file = clang_default_o(input_files[0])
            toolchain.bundle(self.fixname(output_file), input_files, 
                             [x for x in flags if x.startswith('-l')],
                             [x[2:] for x in flags if x.startswith('-L')])
            return 0
        elif '-c' in args or '-S' in args:
            if output_file is None:
                output_file = clang_default_o(input_files[0])

            if input_files[0].lower().endswith('.s') or useAsm(flags):
                # XXX
                return toolchain.compile(input_files,
                                          self.fixname(output_file), 
                                         flags, 
                                         tool=tool)
            elif input_files[0] == '-':
                return toolchain.compile(input_files, self.fixname(output_file), 
                                         flags,
                                         tool=tool)
            else:
                # print input_files
                # c_file = [x for x in input_files 
                #           if x.endswith('.c') or x.endswith('.cpp') 
                #           or x.endswith('.cxx') or x.endswith('.cc')]
                c_file = input_files[0]
                return toolchain.compile([c_file] + [x for x in input_files if x != c_file],
                                         self.fixname(output_file), 
                                         flags,
                                         tool=tool)
        else:
            assert not useAsm(flags) # NOT IMPLEMENTED
            # if any(map(lambda x: '.so' in x, input_files)):
            #     logging.getLogger().info("got .so, skipping")
            stdlibs = ['-lc']
            if self.name == 'clang++':
                stdlibs.append('-lstdc++')

            def needsCompiling(f):
                return f == '-' or f.endswith('.c') or f.endswith('.cpp') or f.endswith('.cxx')
            toCompile = filter(needsCompiling,input_files)
            if toCompile:
                o_files = []
                for fileToCompile in toCompile:
                    tf = tempfile.NamedTemporaryFile(delete=False)
                    retcode = toolchain.compile([fileToCompile], 
                                                self.fixname(tf.name),
                                                flags, tool=tool)
                    o_files.append(tf.name)
                    if retcode != 0:
                        map(os.unlink,o_files)
                        return retcode
                if output_file is None:
                    output_file = 'a.out'
                toLink = [x for x in input_files if x not in toCompile]
                try:
                    retcode = toolchain.link(map(self.fixname,o_files) +
                                             map(self.fixinputname,toLink),
                                             self.fixname(output_file),
                                             flags + stdlibs,
                                             link=True,
                                             save='%s_mani' % output_file)
                except driver.ReturnCode,ex:
                    logging.getLogger().warn("WARNING: manifest link failed for %s" % output_file)
                    logging.getLogger().warn("%s" % ex)
                    retcode = 0
                map(os.unlink,o_files)
            else:
                try:
                    retcode = toolchain.link(map(self.fixname,o_files) +
                                             map(self.fixinputname,toLink),
                                             self.fixname(output_file),
                                             flags + stdlibs,
                                             link=True,
                                             save='%s_mani' % output_file)
                except driver.ReturnCode,ex:
                    logging.getLogger().warn("WARNING: manifest link failed for %s" % output_file)
                    logging.getLogger().warn("%s" % ex)
                    retcode = 0
                map(os.unlink,o_files)
            else:
                if output_file is None:
                    output_file = 'a.out'
                try:
                    retcode = toolchain.link(map(self.fixinputname,input_files),
                                             self.fixname(output_file),
                                             flags + stdlibs, 
                                             save='%s_main.bc' % output_file,
                                             link=True)
                except driver.ReturnCode,ex:
                    logging.getLogger().warn("WARNING: manifest link failed for %s" % output_file)
                    logging.getLogger().warn("%s" % ex)
                    retcode = 0
            return retcode

for x in ['clang', 'clang++', 'clang-cpp']:
    target.register(x, ClangTool(x))