mirror of
https://github.com/danog/gllvm.git
synced 2024-11-30 08:19:01 +01:00
Some procedural abstraction and clean up.
This commit is contained in:
parent
f497d4dee4
commit
4eadb3c7d1
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user