mirror of
https://github.com/danog/gllvm.git
synced 2024-11-30 04:09:02 +01:00
Attempt at making the lto tweaks work properly, and adding the LTO_LINKING_FLAGS environment example.
This commit is contained in:
parent
3937f675c1
commit
dfb22031a1
49
cmd/gparse/main.go
Normal file
49
cmd/gparse/main.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// OCCAM
|
||||||
|
//
|
||||||
|
// Copyright (c) 2017, SRI International
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
// list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// * Neither the name of SRI International nor the names of its contributors may
|
||||||
|
// be used to endorse or promote products derived from this software without
|
||||||
|
// specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/SRI-CSL/gllvm/shared"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Parse command line
|
||||||
|
args := os.Args
|
||||||
|
args = args[1:]
|
||||||
|
parsed := shared.Parse(args)
|
||||||
|
// Print out the result
|
||||||
|
fmt.Printf("Parsed: %v", &parsed)
|
||||||
|
}
|
21
examples/lto/Makefile
Normal file
21
examples/lto/Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
all: main
|
||||||
|
|
||||||
|
main: main.o
|
||||||
|
${CC} -flto a.o main.o -o main
|
||||||
|
|
||||||
|
main.o: main.c a.o
|
||||||
|
${CC} -c main.c -o main.o
|
||||||
|
|
||||||
|
a.o: a.c a.h
|
||||||
|
${CC} -flto -c a.c -o a.o
|
||||||
|
|
||||||
|
plain: main.c a.c a.h
|
||||||
|
${CC} main.c a.c -o plain
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o main plain
|
||||||
|
|
||||||
|
|
24
examples/lto/a.c
Normal file
24
examples/lto/a.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//https://llvm.org/docs/LinkTimeOptimization.html
|
||||||
|
#include "a.h"
|
||||||
|
|
||||||
|
static signed int i = 0;
|
||||||
|
|
||||||
|
void foo2(void) {
|
||||||
|
i = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int foo3() {
|
||||||
|
foo4();
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo1(void) {
|
||||||
|
int data = 0;
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
data = foo3();
|
||||||
|
|
||||||
|
data = data + 42;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
4
examples/lto/a.h
Normal file
4
examples/lto/a.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
//https://llvm.org/docs/LinkTimeOptimization.html
|
||||||
|
extern int foo1(void);
|
||||||
|
extern void foo2(void);
|
||||||
|
extern void foo4(void);
|
11
examples/lto/main.c
Normal file
11
examples/lto/main.c
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//https://llvm.org/docs/LinkTimeOptimization.html
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "a.h"
|
||||||
|
|
||||||
|
void foo4(void) {
|
||||||
|
printf("Hi\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return foo1();
|
||||||
|
}
|
@ -53,19 +53,21 @@ type bitcodeToObjectLink struct {
|
|||||||
func Compile(args []string, compiler string) (exitCode int) {
|
func Compile(args []string, compiler string) (exitCode int) {
|
||||||
|
|
||||||
exitCode = 0
|
exitCode = 0
|
||||||
//in the configureOnly case we have to know the exit code of the compile
|
// in the configureOnly case we have to know the exit code of the compile
|
||||||
//because that is how configure figures out what it can and cannot do.
|
// because that is how configure figures out what it can and cannot do.
|
||||||
|
|
||||||
ok := true
|
ok := true
|
||||||
|
|
||||||
compilerExecName := GetCompilerExecName(compiler)
|
compilerExecName := GetCompilerExecName(compiler)
|
||||||
|
|
||||||
pr := parse(args)
|
pr := Parse(args)
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
// If configure only or print only are set, just execute the compiler
|
LogDebug("Compile using parsed arguments:%v\n", &pr)
|
||||||
if skipBitcodeGeneration(pr) {
|
|
||||||
|
// If configure only, emit-llvm, flto, or print only are set, just execute the compiler
|
||||||
|
if pr.skipBitcodeGeneration() {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go execCompile(compilerExecName, pr, &wg, &ok)
|
go execCompile(compilerExecName, pr, &wg, &ok)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
@ -103,7 +105,7 @@ func Compile(args []string, compiler string) (exitCode int) {
|
|||||||
|
|
||||||
// Compiles bitcode files and mutates the list of bc->obj links to perform + the list of
|
// Compiles bitcode files and mutates the list of bc->obj links to perform + the list of
|
||||||
// new object files to link
|
// new object files to link
|
||||||
func buildAndAttachBitcode(compilerExecName string, pr parserResult, bcObjLinks *[]bitcodeToObjectLink, newObjectFiles *[]string, wg *sync.WaitGroup) {
|
func buildAndAttachBitcode(compilerExecName string, pr ParserResult, bcObjLinks *[]bitcodeToObjectLink, newObjectFiles *[]string, wg *sync.WaitGroup) {
|
||||||
defer (*wg).Done()
|
defer (*wg).Done()
|
||||||
|
|
||||||
var hidden = !pr.IsCompileOnly
|
var hidden = !pr.IsCompileOnly
|
||||||
@ -207,15 +209,18 @@ func attachBitcodePathToObject(bcFile, objFile string) (success bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileTimeLinkFiles(compilerExecName string, pr parserResult, objFiles []string) {
|
func compileTimeLinkFiles(compilerExecName string, pr ParserResult, objFiles []string) {
|
||||||
var outputFile = pr.OutputFilename
|
var outputFile = pr.OutputFilename
|
||||||
if outputFile == "" {
|
if outputFile == "" {
|
||||||
outputFile = "a.out"
|
outputFile = "a.out"
|
||||||
}
|
}
|
||||||
args := objFiles
|
args := []string{}
|
||||||
for _, larg := range pr.LinkArgs {
|
//iam: unclear if this is necessary here
|
||||||
args = append(args, larg)
|
if pr.IsLTO {
|
||||||
|
args = append(args, LLVMLtoLDFLAGS...)
|
||||||
}
|
}
|
||||||
|
args = append(args, objFiles...)
|
||||||
|
args = append(args, pr.LinkArgs...)
|
||||||
args = append(args, "-o", outputFile)
|
args = append(args, "-o", outputFile)
|
||||||
success, err := execCmd(compilerExecName, args, "")
|
success, err := execCmd(compilerExecName, args, "")
|
||||||
if !success {
|
if !success {
|
||||||
@ -226,7 +231,7 @@ func compileTimeLinkFiles(compilerExecName string, pr parserResult, objFiles []s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tries to build the specified source file to object
|
// Tries to build the specified source file to object
|
||||||
func buildObjectFile(compilerExecName string, pr parserResult, srcFile string, objFile string) (success bool) {
|
func buildObjectFile(compilerExecName string, pr ParserResult, srcFile string, objFile string) (success bool) {
|
||||||
args := pr.CompileArgs[:]
|
args := pr.CompileArgs[:]
|
||||||
args = append(args, srcFile, "-c", "-o", objFile)
|
args = append(args, srcFile, "-c", "-o", objFile)
|
||||||
success, err := execCmd(compilerExecName, args, "")
|
success, err := execCmd(compilerExecName, args, "")
|
||||||
@ -239,7 +244,7 @@ func buildObjectFile(compilerExecName string, pr parserResult, srcFile string, o
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tries to build the specified source file to bitcode
|
// Tries to build the specified source file to bitcode
|
||||||
func buildBitcodeFile(compilerExecName string, pr parserResult, srcFile string, bcFile string) (success bool) {
|
func buildBitcodeFile(compilerExecName string, pr ParserResult, srcFile string, bcFile string) (success bool) {
|
||||||
args := pr.CompileArgs[:]
|
args := pr.CompileArgs[:]
|
||||||
//iam: 03/24/2020 extend with the LLVM_BITCODE_GENERATION_FLAGS if any.
|
//iam: 03/24/2020 extend with the LLVM_BITCODE_GENERATION_FLAGS if any.
|
||||||
args = append(args, LLVMbcGen...)
|
args = append(args, LLVMbcGen...)
|
||||||
@ -253,14 +258,57 @@ func buildBitcodeFile(compilerExecName string, pr parserResult, srcFile string,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tries to build object file
|
// Tries to build object file or link...
|
||||||
func execCompile(compilerExecName string, pr parserResult, wg *sync.WaitGroup, ok *bool) {
|
func execCompile(compilerExecName string, pr ParserResult, wg *sync.WaitGroup, ok *bool) {
|
||||||
defer (*wg).Done()
|
defer (*wg).Done()
|
||||||
//iam: strickly speaking we should do more work here depending on whether this is
|
//iam: strickly speaking we should do more work here depending on whether this is
|
||||||
// a compile only, a link only, or ...
|
// a compile only, a link only, or ...
|
||||||
// But for the now, we just remove forbidden arguments
|
// But for the now, we just remove forbidden arguments
|
||||||
var success bool
|
var success bool
|
||||||
var err error
|
var err error
|
||||||
|
// start afresh
|
||||||
|
arguments := []string{}
|
||||||
|
// we are linking rather than compiling
|
||||||
|
if len(pr.InputFiles) == 0 && len(pr.LinkArgs) > 0 {
|
||||||
|
if pr.IsLTO {
|
||||||
|
arguments = append(arguments, LLVMLtoLDFLAGS...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//iam: this is clunky. is there a better way?
|
||||||
|
if len(pr.ForbiddenFlags) > 0 {
|
||||||
|
for _, arg := range pr.InputList {
|
||||||
|
found := false
|
||||||
|
for _, bad := range pr.ForbiddenFlags {
|
||||||
|
if bad == arg {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
arguments = append(arguments, arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arguments = append(arguments, pr.InputList...)
|
||||||
|
}
|
||||||
|
LogDebug("Calling execCmd(%v, %v)", compilerExecName, arguments)
|
||||||
|
success, err = execCmd(compilerExecName, arguments, "")
|
||||||
|
if !success {
|
||||||
|
LogError("Failed to compile using given arguments:\n%v %v\nexit status: %v\n", compilerExecName, arguments, err)
|
||||||
|
*ok = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tries to build object file
|
||||||
|
|
||||||
|
func oldExecCompile(compilerExecName string, pr ParserResult, wg *sync.WaitGroup, ok *bool) {
|
||||||
|
defer (*wg).Done()
|
||||||
|
//iam: strickly speaking we should do more work here depending on whether this is
|
||||||
|
// a compile only, a link only, or ...
|
||||||
|
// But for the now, we just remove forbidden arguments
|
||||||
|
var success bool
|
||||||
|
var err error
|
||||||
|
|
||||||
if len(pr.ForbiddenFlags) > 0 {
|
if len(pr.ForbiddenFlags) > 0 {
|
||||||
filteredArgs := pr.InputList[:0]
|
filteredArgs := pr.InputList[:0]
|
||||||
for _, arg := range pr.InputList {
|
for _, arg := range pr.InputList {
|
||||||
|
@ -53,9 +53,11 @@ package shared
|
|||||||
// See https://github.com/travitch/whole-program-llvm/issues/96 for details.
|
// See https://github.com/travitch/whole-program-llvm/issues/96 for details.
|
||||||
//
|
//
|
||||||
// 1.2.7 August 4 2020 William Woodruff's (@woodruffw) tweaks to the get-bc command (a strict mode).
|
// 1.2.7 August 4 2020 William Woodruff's (@woodruffw) tweaks to the get-bc command (a strict mode).
|
||||||
|
//
|
||||||
|
// 1.2.8 October 11 2020 Wensheng Tang's (@legendtang) requests and fixes to the -flto issues.
|
||||||
|
|
||||||
const gllvmVersion = "1.2.7"
|
const gllvmVersion = "1.2.8"
|
||||||
const gllvmReleaseDate = "August 4 2020"
|
const gllvmReleaseDate = "October 11 2020"
|
||||||
|
|
||||||
const osDARWIN = "darwin"
|
const osDARWIN = "darwin"
|
||||||
const osLINUX = "linux"
|
const osLINUX = "linux"
|
||||||
|
@ -86,6 +86,9 @@ var LLVMLd string
|
|||||||
//LLVMbcGen is the list of args to pass to clang during the bitcode generation step.
|
//LLVMbcGen is the list of args to pass to clang during the bitcode generation step.
|
||||||
var LLVMbcGen []string
|
var LLVMbcGen []string
|
||||||
|
|
||||||
|
//LLVMLtoLDFLAGS is the list of extra flags to pass to the linking steps, when unde -flto
|
||||||
|
var LLVMLtoLDFLAGS []string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
envpath = "LLVM_COMPILER_PATH"
|
envpath = "LLVM_COMPILER_PATH"
|
||||||
envcc = "LLVM_CC_NAME"
|
envcc = "LLVM_CC_NAME"
|
||||||
@ -102,6 +105,9 @@ const (
|
|||||||
//iam: 03/24/2020 new feature to pass things like "-flto -fwhole-program-vtables"
|
//iam: 03/24/2020 new feature to pass things like "-flto -fwhole-program-vtables"
|
||||||
// to clang during the bitcode generation step
|
// to clang during the bitcode generation step
|
||||||
envbcgen = "LLVM_BITCODE_GENERATION_FLAGS"
|
envbcgen = "LLVM_BITCODE_GENERATION_FLAGS"
|
||||||
|
//iam: 10/11/2020 extra linking arguments to add to the linking step when we are doing
|
||||||
|
// link time optimization.
|
||||||
|
envltolink = "LTO_LINKING_FLAGS"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -138,6 +144,7 @@ func ResetEnvironment() {
|
|||||||
LLVMObjcopy = ""
|
LLVMObjcopy = ""
|
||||||
LLVMLd = ""
|
LLVMLd = ""
|
||||||
LLVMbcGen = []string{}
|
LLVMbcGen = []string{}
|
||||||
|
LLVMLtoLDFLAGS = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchEnvironment is used in initializing our globals, it is also used in testing
|
// FetchEnvironment is used in initializing our globals, it is also used in testing
|
||||||
@ -158,5 +165,5 @@ func FetchEnvironment() {
|
|||||||
LLVMLd = os.Getenv(envld)
|
LLVMLd = os.Getenv(envld)
|
||||||
|
|
||||||
LLVMbcGen = strings.Fields(os.Getenv(envbcgen))
|
LLVMbcGen = strings.Fields(os.Getenv(envbcgen))
|
||||||
|
LLVMLtoLDFLAGS = strings.Fields(os.Getenv(envltolink))
|
||||||
}
|
}
|
||||||
|
146
shared/parser.go
146
shared/parser.go
@ -43,7 +43,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type parserResult struct {
|
//ParserResult is the result of parsing and partioning the command line arguments.
|
||||||
|
type ParserResult struct {
|
||||||
InputList []string
|
InputList []string
|
||||||
InputFiles []string
|
InputFiles []string
|
||||||
ObjectFiles []string
|
ObjectFiles []string
|
||||||
@ -58,9 +59,49 @@ type parserResult struct {
|
|||||||
IsAssembly bool
|
IsAssembly bool
|
||||||
IsCompileOnly bool
|
IsCompileOnly bool
|
||||||
IsEmitLLVM bool
|
IsEmitLLVM bool
|
||||||
|
IsLTO bool
|
||||||
IsPrintOnly bool
|
IsPrintOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const parserResultFormat = `
|
||||||
|
InputList: %v
|
||||||
|
InputFiles: %v
|
||||||
|
ObjectFiles: %v
|
||||||
|
OutputFilename: %v
|
||||||
|
CompileArgs: %v
|
||||||
|
LinkArgs: %v
|
||||||
|
ForbiddenFlags: %v
|
||||||
|
IsVerbose: %v
|
||||||
|
IsDependencyOnly: %v
|
||||||
|
IsPreprocessOnly: %v
|
||||||
|
IsAssembleOnly: %v
|
||||||
|
IsAssembly: %v
|
||||||
|
IsCompileOnly: %v
|
||||||
|
IsEmitLLVM: %v
|
||||||
|
IsLTO: %v
|
||||||
|
IsPrintOnly: %v
|
||||||
|
`
|
||||||
|
|
||||||
|
func (pr *ParserResult) String() string {
|
||||||
|
return fmt.Sprintf(parserResultFormat,
|
||||||
|
pr.InputList,
|
||||||
|
pr.InputFiles,
|
||||||
|
pr.ObjectFiles,
|
||||||
|
pr.OutputFilename,
|
||||||
|
pr.CompileArgs,
|
||||||
|
pr.LinkArgs,
|
||||||
|
pr.ForbiddenFlags,
|
||||||
|
pr.IsVerbose,
|
||||||
|
pr.IsDependencyOnly,
|
||||||
|
pr.IsPreprocessOnly,
|
||||||
|
pr.IsAssembleOnly,
|
||||||
|
pr.IsAssembly,
|
||||||
|
pr.IsCompileOnly,
|
||||||
|
pr.IsEmitLLVM,
|
||||||
|
pr.IsLTO,
|
||||||
|
pr.IsPrintOnly)
|
||||||
|
}
|
||||||
|
|
||||||
type flagInfo struct {
|
type flagInfo struct {
|
||||||
arity int
|
arity int
|
||||||
handler func(string, []string)
|
handler func(string, []string)
|
||||||
@ -71,31 +112,50 @@ type argPattern struct {
|
|||||||
finfo flagInfo
|
finfo flagInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func skipBitcodeGeneration(pr parserResult) bool {
|
func (pr *ParserResult) skipBitcodeGeneration() bool {
|
||||||
|
reason := "No particular reason"
|
||||||
|
retval := false
|
||||||
|
squark := LogDebug
|
||||||
if LLVMConfigureOnly != "" {
|
if LLVMConfigureOnly != "" {
|
||||||
return true
|
reason = "are in configure only mode"
|
||||||
|
retval = true
|
||||||
|
} else if len(pr.InputFiles) == 0 {
|
||||||
|
reason = "did not see any input files"
|
||||||
|
retval = true
|
||||||
|
} else if pr.IsEmitLLVM {
|
||||||
|
squark = LogWarning
|
||||||
|
reason = "are in emit-llvm mode, and so the compiler is doing the job for us"
|
||||||
|
retval = true
|
||||||
|
} else if pr.IsLTO {
|
||||||
|
squark = LogWarning
|
||||||
|
reason = "are doing link time optimization, and so the compiler is doing the job for us"
|
||||||
|
retval = true
|
||||||
|
} else if pr.IsAssembly {
|
||||||
|
reason = "the input file(s) are written in assembly"
|
||||||
|
squark = LogWarning
|
||||||
|
retval = true
|
||||||
|
} else if pr.IsAssembleOnly {
|
||||||
|
reason = "are assembling only, and so have nowhere to embed the path of the bitcode"
|
||||||
|
retval = true
|
||||||
|
} else if pr.IsDependencyOnly && !pr.IsCompileOnly {
|
||||||
|
reason = "are only computing dependencies at this stage"
|
||||||
|
retval = true
|
||||||
|
} else if pr.IsPreprocessOnly {
|
||||||
|
reason = "are in preprocess only mode"
|
||||||
|
retval = true
|
||||||
|
} else if pr.IsPrintOnly {
|
||||||
|
reason = "are in print only mode, and so have nowhere to embed the path of the bitcode"
|
||||||
|
retval = true
|
||||||
}
|
}
|
||||||
if len(pr.InputFiles) == 0 ||
|
if retval {
|
||||||
pr.IsEmitLLVM ||
|
squark(" We are skipping bitcode generation because we %v.\n", reason)
|
||||||
pr.IsAssembly ||
|
|
||||||
pr.IsAssembleOnly ||
|
|
||||||
(pr.IsDependencyOnly && !pr.IsCompileOnly) ||
|
|
||||||
pr.IsPreprocessOnly ||
|
|
||||||
pr.IsPrintOnly {
|
|
||||||
// Lots of reasons why we don't produce bitcode. But IsEmitLLVM is the most unusual.
|
|
||||||
if pr.IsEmitLLVM {
|
|
||||||
// Either we are being called with -emit-llvm or -flto. Either way all bets are off.
|
|
||||||
LogWarning("The compiler is producing bitcode instead of object code. get-bc is unlikely to work: %v\n", pr.OutputFilename)
|
|
||||||
}
|
}
|
||||||
|
return retval
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse(argList []string) parserResult {
|
//Parse analyzes the command line aruguments and returns the result of that analysis.
|
||||||
var pr = parserResult{}
|
func Parse(argList []string) ParserResult {
|
||||||
|
var pr = ParserResult{}
|
||||||
pr.InputList = argList
|
pr.InputList = argList
|
||||||
|
|
||||||
var argsExactMatches = map[string]flagInfo{
|
var argsExactMatches = map[string]flagInfo{
|
||||||
@ -350,7 +410,7 @@ func parse(argList []string) parserResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return the object and bc filenames that correspond to the i-th source file
|
// Return the object and bc filenames that correspond to the i-th source file
|
||||||
func getArtifactNames(pr parserResult, srcFileIndex int, hidden bool) (objBase string, bcBase string) {
|
func getArtifactNames(pr ParserResult, srcFileIndex int, hidden bool) (objBase string, bcBase string) {
|
||||||
if len(pr.InputFiles) == 1 && pr.IsCompileOnly && len(pr.OutputFilename) > 0 {
|
if len(pr.InputFiles) == 1 && pr.IsCompileOnly && len(pr.OutputFilename) > 0 {
|
||||||
objBase = pr.OutputFilename
|
objBase = pr.OutputFilename
|
||||||
dir, baseName := path.Split(objBase)
|
dir, baseName := path.Split(objBase)
|
||||||
@ -381,7 +441,7 @@ func getHashedPath(path string) string {
|
|||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) inputFileCallback(flag string, _ []string) {
|
func (pr *ParserResult) inputFileCallback(flag string, _ []string) {
|
||||||
var regExp = regexp.MustCompile(`\.(s|S)$`)
|
var regExp = regexp.MustCompile(`\.(s|S)$`)
|
||||||
pr.InputFiles = append(pr.InputFiles, flag)
|
pr.InputFiles = append(pr.InputFiles, flag)
|
||||||
if regExp.MatchString(flag) {
|
if regExp.MatchString(flag) {
|
||||||
@ -389,11 +449,11 @@ func (pr *parserResult) inputFileCallback(flag string, _ []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) outputFileCallback(_ string, args []string) {
|
func (pr *ParserResult) outputFileCallback(_ string, args []string) {
|
||||||
pr.OutputFilename = args[0]
|
pr.OutputFilename = args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) objectFileCallback(flag string, _ []string) {
|
func (pr *ParserResult) objectFileCallback(flag string, _ []string) {
|
||||||
// FIXME: the object file is appended to ObjectFiles that
|
// FIXME: the object file is appended to ObjectFiles that
|
||||||
// is used nowhere else in the code
|
// is used nowhere else in the code
|
||||||
pr.ObjectFiles = append(pr.ObjectFiles, flag)
|
pr.ObjectFiles = append(pr.ObjectFiles, flag)
|
||||||
@ -402,76 +462,76 @@ func (pr *parserResult) objectFileCallback(flag string, _ []string) {
|
|||||||
pr.LinkArgs = append(pr.LinkArgs, flag)
|
pr.LinkArgs = append(pr.LinkArgs, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) preprocessOnlyCallback(_ string, _ []string) {
|
func (pr *ParserResult) preprocessOnlyCallback(_ string, _ []string) {
|
||||||
pr.IsPreprocessOnly = true
|
pr.IsPreprocessOnly = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) dependencyOnlyCallback(flag string, _ []string) {
|
func (pr *ParserResult) dependencyOnlyCallback(flag string, _ []string) {
|
||||||
pr.IsDependencyOnly = true
|
pr.IsDependencyOnly = true
|
||||||
pr.CompileArgs = append(pr.CompileArgs, flag)
|
pr.CompileArgs = append(pr.CompileArgs, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) printOnlyCallback(flag string, _ []string) {
|
func (pr *ParserResult) printOnlyCallback(flag string, _ []string) {
|
||||||
pr.IsPrintOnly = true
|
pr.IsPrintOnly = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) assembleOnlyCallback(_ string, _ []string) {
|
func (pr *ParserResult) assembleOnlyCallback(_ string, _ []string) {
|
||||||
pr.IsAssembleOnly = true
|
pr.IsAssembleOnly = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) verboseFlagCallback(_ string, _ []string) {
|
func (pr *ParserResult) verboseFlagCallback(_ string, _ []string) {
|
||||||
pr.IsVerbose = true
|
pr.IsVerbose = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) compileOnlyCallback(_ string, _ []string) {
|
func (pr *ParserResult) compileOnlyCallback(_ string, _ []string) {
|
||||||
pr.IsCompileOnly = true
|
pr.IsCompileOnly = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) emitLLVMCallback(_ string, _ []string) {
|
func (pr *ParserResult) emitLLVMCallback(_ string, _ []string) {
|
||||||
pr.IsCompileOnly = true
|
pr.IsCompileOnly = true
|
||||||
pr.IsEmitLLVM = true
|
pr.IsEmitLLVM = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) linkTimeOptimizationCallback(_ string, _ []string) {
|
func (pr *ParserResult) linkTimeOptimizationCallback(_ string, _ []string) {
|
||||||
pr.IsEmitLLVM = true
|
pr.IsLTO = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) linkUnaryCallback(flag string, _ []string) {
|
func (pr *ParserResult) linkUnaryCallback(flag string, _ []string) {
|
||||||
pr.LinkArgs = append(pr.LinkArgs, flag)
|
pr.LinkArgs = append(pr.LinkArgs, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) compileUnaryCallback(flag string, _ []string) {
|
func (pr *ParserResult) compileUnaryCallback(flag string, _ []string) {
|
||||||
pr.CompileArgs = append(pr.CompileArgs, flag)
|
pr.CompileArgs = append(pr.CompileArgs, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) warningLinkUnaryCallback(flag string, _ []string) {
|
func (pr *ParserResult) warningLinkUnaryCallback(flag string, _ []string) {
|
||||||
LogWarning("The flag %v cannot be used with this tool, we ignore it, else we lose the bitcode section.\n", flag)
|
LogWarning("The flag %v cannot be used with this tool, we ignore it, else we lose the bitcode section.\n", flag)
|
||||||
pr.ForbiddenFlags = append(pr.ForbiddenFlags, flag)
|
pr.ForbiddenFlags = append(pr.ForbiddenFlags, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) defaultBinaryCallback(_ string, _ []string) {
|
func (pr *ParserResult) defaultBinaryCallback(_ string, _ []string) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) dependencyBinaryCallback(flag string, args []string) {
|
func (pr *ParserResult) dependencyBinaryCallback(flag string, args []string) {
|
||||||
pr.CompileArgs = append(pr.CompileArgs, flag, args[0])
|
pr.CompileArgs = append(pr.CompileArgs, flag, args[0])
|
||||||
pr.IsDependencyOnly = true
|
pr.IsDependencyOnly = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) compileBinaryCallback(flag string, args []string) {
|
func (pr *ParserResult) compileBinaryCallback(flag string, args []string) {
|
||||||
pr.CompileArgs = append(pr.CompileArgs, flag, args[0])
|
pr.CompileArgs = append(pr.CompileArgs, flag, args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) linkBinaryCallback(flag string, args []string) {
|
func (pr *ParserResult) linkBinaryCallback(flag string, args []string) {
|
||||||
pr.LinkArgs = append(pr.LinkArgs, flag, args[0])
|
pr.LinkArgs = append(pr.LinkArgs, flag, args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) compileLinkUnaryCallback(flag string, _ []string) {
|
func (pr *ParserResult) compileLinkUnaryCallback(flag string, _ []string) {
|
||||||
pr.LinkArgs = append(pr.LinkArgs, flag)
|
pr.LinkArgs = append(pr.LinkArgs, flag)
|
||||||
pr.CompileArgs = append(pr.CompileArgs, flag)
|
pr.CompileArgs = append(pr.CompileArgs, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *parserResult) compileLinkBinaryCallback(flag string, args []string) {
|
func (pr *ParserResult) compileLinkBinaryCallback(flag string, args []string) {
|
||||||
pr.LinkArgs = append(pr.LinkArgs, flag, args[0])
|
pr.LinkArgs = append(pr.LinkArgs, flag, args[0])
|
||||||
pr.CompileArgs = append(pr.CompileArgs, flag, args[0])
|
pr.CompileArgs = append(pr.CompileArgs, flag, args[0])
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user