Some procedural abstraction and clean up.

This commit is contained in:
Ian A. Mason 2018-05-11 07:13:13 -07:00
parent f497d4dee4
commit 4eadb3c7d1
3 changed files with 94 additions and 92 deletions

View File

@ -50,10 +50,10 @@ import (
) )
type extractionArgs struct { type extractionArgs struct {
Verbose bool Verbose bool // inform the user of what is going on
WriteManifest bool WriteManifest bool // write a manifest of bitcode files used
SortBitcodeFiles bool SortBitcodeFiles bool // sort the arguments to linking and archiving (debugging too)
BuildBitcodeArchive bool BuildBitcodeModule bool // buld an archive rather than a module
KeepTemp bool // keep temporary linking folder KeepTemp bool // keep temporary linking folder
LinkArgSize int // maximum size of a llvm-link command line LinkArgSize int // maximum size of a llvm-link command line
InputType int InputType int
@ -95,7 +95,7 @@ func Extract(args []string) {
if ea.OutputFile == "" { if ea.OutputFile == "" {
if ea.InputType == fileTypeARCHIVE || ea.InputType == fileTypeTHINARCHIVE { if ea.InputType == fileTypeARCHIVE || ea.InputType == fileTypeTHINARCHIVE {
var ext string var ext string
if ea.BuildBitcodeArchive { if ea.BuildBitcodeModule {
ext = ".a.bc" ext = ".a.bc"
} else { } else {
ext = ".bca" ext = ".bca"
@ -161,7 +161,7 @@ func parseSwitches() (ea extractionArgs) {
sortBitcodeFilesPtr := flag.Bool("s", false, "sort the bitcode files") sortBitcodeFilesPtr := flag.Bool("s", false, "sort the bitcode files")
buildBitcodeArchive := flag.Bool("b", false, "build a bitcode module(FIXME? should this be archive)") buildBitcodeModule := flag.Bool("b", false, "build a bitcode module")
outputFilePtr := flag.String("o", "", "the output file") outputFilePtr := flag.String("o", "", "the output file")
@ -169,7 +169,7 @@ func parseSwitches() (ea extractionArgs) {
linkerNamePtr := flag.String("l", "", "the llvm linker") linkerNamePtr := flag.String("l", "", "the llvm linker")
linkArgSizePtr := flag.Int("n", 0, "maximum llvm-link command line size") linkArgSizePtr := flag.Int("n", 0, "maximum llvm-link command line size (in bytes)")
keepTempPtr := flag.Bool("t", false, "keep temporary linking folder") keepTempPtr := flag.Bool("t", false, "keep temporary linking folder")
@ -178,7 +178,7 @@ func parseSwitches() (ea extractionArgs) {
ea.Verbose = *verbosePtr ea.Verbose = *verbosePtr
ea.WriteManifest = *writeManifestPtr ea.WriteManifest = *writeManifestPtr
ea.SortBitcodeFiles = *sortBitcodeFilesPtr ea.SortBitcodeFiles = *sortBitcodeFilesPtr
ea.BuildBitcodeArchive = *buildBitcodeArchive ea.BuildBitcodeModule = *buildBitcodeModule
ea.LinkArgSize = *linkArgSizePtr ea.LinkArgSize = *linkArgSizePtr
ea.KeepTemp = *keepTempPtr ea.KeepTemp = *keepTempPtr
@ -192,7 +192,7 @@ func parseSwitches() (ea extractionArgs) {
LogInfo("ea.Verbose: %v\n", ea.Verbose) LogInfo("ea.Verbose: %v\n", ea.Verbose)
LogInfo("ea.WriteManifest: %v\n", ea.WriteManifest) LogInfo("ea.WriteManifest: %v\n", ea.WriteManifest)
LogInfo("ea.BuildBitcodeArchive: %v\n", ea.BuildBitcodeArchive) LogInfo("ea.BuildBitcodeModule: %v\n", ea.BuildBitcodeModule)
LogInfo("ea.ArchiverName: %v\n", ea.ArchiverName) LogInfo("ea.ArchiverName: %v\n", ea.ArchiverName)
LogInfo("ea.LinkerName: %v\n", ea.LinkerName) LogInfo("ea.LinkerName: %v\n", ea.LinkerName)
LogInfo("ea.OutputFile: %v\n", ea.OutputFile) LogInfo("ea.OutputFile: %v\n", ea.OutputFile)
@ -224,7 +224,8 @@ func parseSwitches() (ea extractionArgs) {
func handleExecutable(ea extractionArgs) { func handleExecutable(ea extractionArgs) {
artifactPaths := ea.Extractor(ea.InputFile) artifactPaths := ea.Extractor(ea.InputFile)
if len(artifactPaths) < 20 { //naert: to avoid saturating the log when dealing with big file lists if len(artifactPaths) < 20 {
// naert: to avoid saturating the log when dealing with big file lists
LogInfo("handleExecutable: artifactPaths = %v\n", artifactPaths) LogInfo("handleExecutable: artifactPaths = %v\n", artifactPaths)
} }
@ -248,7 +249,7 @@ func handleExecutable(ea extractionArgs) {
writeManifest(ea, filesToLink, artifactPaths) writeManifest(ea, filesToLink, artifactPaths)
} }
extractTimeLinkFiles(ea, filesToLink) linkBitcodeFiles(ea, filesToLink)
} }
func handleThinArchive(ea extractionArgs) { func handleThinArchive(ea extractionArgs) {
@ -292,8 +293,8 @@ func handleThinArchive(ea extractionArgs) {
} }
// Build archive // Build archive
if ea.BuildBitcodeArchive { if ea.BuildBitcodeModule {
extractTimeLinkFiles(ea, bcFiles) linkBitcodeFiles(ea, bcFiles)
} else { } else {
archiveBcFiles(ea, bcFiles) archiveBcFiles(ea, bcFiles)
} }
@ -428,8 +429,8 @@ func handleArchive(ea extractionArgs) {
} }
// Build archive // Build archive
if ea.BuildBitcodeArchive { if ea.BuildBitcodeModule {
extractTimeLinkFiles(ea, bcFiles) linkBitcodeFiles(ea, bcFiles)
} else { } else {
archiveBcFiles(ea, bcFiles) archiveBcFiles(ea, bcFiles)
} }
@ -475,17 +476,14 @@ func getsize(stringslice []string) (totalLength int) {
} }
return totalLength return totalLength
} }
func formatStdOut(stdout bytes.Buffer, usefulIndex int) string { func formatStdOut(stdout bytes.Buffer, usefulIndex int) string {
infoArr := strings.Split(stdout.String(), "\n")[usefulIndex] infoArr := strings.Split(stdout.String(), "\n")[usefulIndex]
ret := strings.Fields(infoArr) ret := strings.Fields(infoArr)
return ret[0] return ret[0]
} }
func extractTimeLinkFiles(ea extractionArgs, filesToLink []string) { func fetchArgMax(ea extractionArgs) (argMax int) {
var linkArgs []string
var tmpFileList []string
var argMax int //llvm-link command line maximum size
// Extracting the command line max size from the environment if it is not specified
if ea.LinkArgSize == 0 { if ea.LinkArgSize == 0 {
getArgMax := exec.Command("getconf", "ARG_MAX") getArgMax := exec.Command("getconf", "ARG_MAX")
var argMaxStr bytes.Buffer var argMaxStr bytes.Buffer
@ -502,19 +500,19 @@ func extractTimeLinkFiles(ea extractionArgs, filesToLink []string) {
} else { } else {
argMax = ea.LinkArgSize argMax = ea.LinkArgSize
} }
LogInfo("argMax = %v\n", argMax)
return
}
if ea.Verbose { func linkBitcodeFilesIncrementally(ea extractionArgs, filesToLink []string, argMax int, linkArgs []string) {
linkArgs = append(linkArgs, "-v") var tmpFileList []string
}
if getsize(filesToLink) > argMax { //command line size too large for the OS
// Create tmp dir // Create tmp dir
tmpDirName, err := ioutil.TempDir(".", "glinking") tmpDirName, err := ioutil.TempDir(".", "glinking")
if err != nil { if err != nil {
LogFatal("The temporary directory in which to put temporary linking files could not be created.") LogFatal("The temporary directory in which to put temporary linking files could not be created.")
} }
if !ea.KeepTemp { // delete temporary folder after used unless told otherwise if !ea.KeepTemp {
// delete temporary folder after used unless told otherwise
LogInfo("Temporary folder will be deleted") LogInfo("Temporary folder will be deleted")
defer CheckDefer(func() error { return os.RemoveAll(tmpDirName) }) defer CheckDefer(func() error { return os.RemoveAll(tmpDirName) })
} else { } else {
@ -569,6 +567,17 @@ func extractTimeLinkFiles(ea extractionArgs, filesToLink []string) {
LogFatal("There was an error linking input files into %s because %v.\n", ea.OutputFile, err) LogFatal("There was an error linking input files into %s because %v.\n", ea.OutputFile, err)
} }
LogWarning("Bitcode file extracted to: %s, from files %v \n", ea.OutputFile, tmpFileList) LogWarning("Bitcode file extracted to: %s, from files %v \n", ea.OutputFile, tmpFileList)
}
func linkBitcodeFiles(ea extractionArgs, filesToLink []string) {
var linkArgs []string
// Extracting the command line max size from the environment if it is not specified
argMax := fetchArgMax(ea)
if ea.Verbose {
linkArgs = append(linkArgs, "-v")
}
if getsize(filesToLink) > argMax { //command line size too large for the OS (necessitated by chromium)
linkBitcodeFilesIncrementally(ea, filesToLink, argMax, linkArgs)
} else { } else {
linkArgs = append(linkArgs, "-o", ea.OutputFile) linkArgs = append(linkArgs, "-o", ea.OutputFile)
linkArgs = append(linkArgs, filesToLink...) linkArgs = append(linkArgs, filesToLink...)
@ -578,7 +587,6 @@ func extractTimeLinkFiles(ea extractionArgs, filesToLink []string) {
} }
LogWarning("Bitcode file extracted to: %s \n", ea.OutputFile) LogWarning("Bitcode file extracted to: %s \n", ea.OutputFile)
} }
} }
func extractSectionDarwin(inputFile string) (contents []string) { func extractSectionDarwin(inputFile string) (contents []string) {

View File

@ -74,8 +74,7 @@ func init() {
} }
} }
if LLVMLoggingFile != "" { if LLVMLoggingFile != "" {
//FIXME: is it overboard to defer a close? the OS will close when the process gets cleaned up, do we win //the OS will close when the process gets cleaned up, do we don't gain anything by being OCD.
//anything by being OCD?
if loggingFP, err := os.OpenFile(LLVMLoggingFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600); err == nil { if loggingFP, err := os.OpenFile(LLVMLoggingFile, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600); err == nil {
loggingFilePointer = loggingFP loggingFilePointer = loggingFP
} }
@ -89,10 +88,6 @@ func makeLogger(lvl int) func(format string, a ...interface{}) {
if !strings.HasSuffix(msg, "\n") { if !strings.HasSuffix(msg, "\n") {
msg += "\n" msg += "\n"
} }
//FIXME: (?) if loggingFilePointer != os.Stderr, we could multiplex here
//and send output to both os.Stderr and loggingFilePointer. We wouldn't
//want the user to miss any excitement. Then the sanity checker would not
//need to futz with it.
prefix := loggingPrefixes[lvl] prefix := loggingPrefixes[lvl]
if len(prefix) > 0 { if len(prefix) > 0 {
_, err := loggingFilePointer.WriteString(prefix) _, err := loggingFilePointer.WriteString(prefix)

View File

@ -178,7 +178,7 @@ func checkCompilers() bool {
informUser("The CXX compiler %s is:\n\n\t%s\n\n", cxx, extractLine(cxxVersion, 0)) informUser("The CXX compiler %s is:\n\n\t%s\n\n", cxx, extractLine(cxxVersion, 0))
} }
//FIXME: why "or" rather than "and"? //FIXME: why "or" rather than "and"? BECAUSE: if you only need CC, not having CXX is not an error.
return ccOK || cxxOK return ccOK || cxxOK
} }
@ -199,7 +199,6 @@ func extractLine(version string, n int) string {
} }
// FIXME: this and execCmd in utils.go could be one routine, if that seems reasonable, or is it overboard?
// Executes a command then returns true for success, false if there was an error, err is either nil or the error. // Executes a command then returns true for success, false if there was an error, err is either nil or the error.
func checkExecutable(cmdExecName string, varg string) (success bool, output string, err error) { func checkExecutable(cmdExecName string, varg string) (success bool, output string, err error) {
cmd := exec.Command(cmdExecName, varg) cmd := exec.Command(cmdExecName, varg)