diff --git a/README.md b/README.md index 480a22f..fe7f986 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ To install, simply do (making sure to include those `...`) go get github.com/SRI-CSL/gllvm/cmd/... ``` This should install four binaries: `gclang`, `gclang++`, `get-bc`, and `gsanity-check` -in the `$GOPATH/bin` directory. +in the `$GOPATH/bin` directory. ## Usage @@ -236,6 +236,14 @@ environment variables. For more details of what's under the `gllvm` hood, try gsanity-check -e ``` +## Customizing the BitCode Generation (e.g. LTO) + +In some situations it is desirable to pass certain flags to `clang` in the step that +produces the bitcode. This can be fulfilled by setting the +`LLVM_BITCODE_GENERATION_FLAGS` environment variable to the desired +flags, for example `"-flto -fwhole-program-vtables"`. + + ## License `gllvm` is released under a BSD license. See the file `LICENSE` for [details.](LICENSE) diff --git a/shared/compiler.go b/shared/compiler.go index 856953a..d819bfd 100644 --- a/shared/compiler.go +++ b/shared/compiler.go @@ -241,6 +241,8 @@ func buildObjectFile(compilerExecName string, pr parserResult, srcFile string, o // Tries to build the specified source file to bitcode func buildBitcodeFile(compilerExecName string, pr parserResult, srcFile string, bcFile string) (success bool) { args := pr.CompileArgs[:] + //iam: 03/24/2020 extend with the LLVM_BITCODE_GENERATION_FLAGS if any. + args = append(args, LLVMbcGen...) args = append(args, "-emit-llvm", "-c", srcFile, "-o", bcFile) success, err := execCmd(compilerExecName, args, "") if !success { diff --git a/shared/constants.go b/shared/constants.go index 38061e4..4c83e69 100644 --- a/shared/constants.go +++ b/shared/constants.go @@ -48,9 +48,13 @@ package shared // 1.2.4 June 21 2019 Random fixes (basically the same as wllvm 1.2.7) // // 1.2.5 October 23 2019 Fixes for issues #30 and #31. Plus a new branch where I can futz hygenically. +// +// 1.2.6 March 24 2020 Added the support for the LLVM_BITCODE_GENERATION_FLAGS environment variable. +// See https://github.com/travitch/whole-program-llvm/issues/96 for details. +// -const gllvmVersion = "1.2.5" -const gllvmReleaseDate = "October 23 2019" +const gllvmVersion = "1.2.6" +const gllvmReleaseDate = "March 24 2020" const osDARWIN = "darwin" const osLINUX = "linux" diff --git a/shared/environment.go b/shared/environment.go index 538ac04..6e044c6 100644 --- a/shared/environment.go +++ b/shared/environment.go @@ -35,6 +35,7 @@ package shared import ( "os" + "strings" ) const ( @@ -82,6 +83,9 @@ var LLVMObjcopy string //LLVMLd is the path to the ld executable used to attach the bitcode on OSX. var LLVMLd string +//LLVMbcGen is the list of args to pass to clang during the bitcode generation step. +var LLVMbcGen []string + const ( envpath = "LLVM_COMPILER_PATH" envcc = "LLVM_CC_NAME" @@ -95,14 +99,17 @@ const ( envld = "GLLVM_LD" //iam: we are deviating from wllvm here. envobjcopy = "GLLVM_OBJCOPY" //iam: we are deviating from wllvm here. //wllvm uses a BINUTILS_TARGET_PREFIX, which seems less general. + //iam: 03/24/2020 new feature to pass things like "-flto -fwhole-program-vtables" + // to clang during the bitcode generation step + envbcgen = "LLVM_BITCODE_GENERATION_FLAGS" ) func init() { FetchEnvironment() } -func printEnvironment() { - vars := []string{envpath, envcc, envcxx, envar, envlnk, envcfg, envbc, envlvl, envfile, envobjcopy, envld} +func PrintEnvironment() { + vars := []string{envpath, envcc, envcxx, envar, envlnk, envcfg, envbc, envlvl, envfile, envobjcopy, envld, envbcgen} informUser("\nLiving in this environment:\n\n") for _, v := range vars { @@ -116,7 +123,23 @@ func printEnvironment() { } -// used in testing +// also used in testing +func ResetEnvironment() { + LLVMToolChainBinDir = "" + LLVMCCName = "" + LLVMCXXName = "" + LLVMARName = "" + LLVMLINKName = "" + LLVMConfigureOnly = "" + LLVMBitcodeStorePath = "" + LLVMLoggingLevel = "" + LLVMLoggingFile = "" + LLVMObjcopy = "" + LLVMLd = "" + LLVMbcGen = []string{} +} + +// also used in testing func FetchEnvironment() { LLVMToolChainBinDir = os.Getenv(envpath) LLVMCCName = os.Getenv(envcc) @@ -132,4 +155,7 @@ func FetchEnvironment() { LLVMObjcopy = os.Getenv(envobjcopy) LLVMLd = os.Getenv(envld) + + LLVMbcGen = strings.Fields(os.Getenv(envbcgen)) + } diff --git a/shared/sanity.go b/shared/sanity.go index 4e79398..3e8b10b 100644 --- a/shared/sanity.go +++ b/shared/sanity.go @@ -108,7 +108,7 @@ func SanityCheck() { informUser("\nVersion info: gsanity-check version %v\nReleased: %v\n", gllvmVersion, gllvmReleaseDate) if sa.Environment { - printEnvironment() + PrintEnvironment() } checkLogging() diff --git a/tests/env_and_arg_test.go b/tests/env_and_arg_test.go index db0daca..204732b 100644 --- a/tests/env_and_arg_test.go +++ b/tests/env_and_arg_test.go @@ -41,6 +41,13 @@ func Test_env_and_args(t *testing.T) { args := []string{"get-bc", "-v", "../data/hello"} + if verbose { + shared.PrintEnvironment() + } + + + shared.ResetEnvironment() + ea := shared.ParseSwitches(args) if !ea.Verbose { t.Errorf("ParseSwitches: -v flag not working\n") @@ -52,6 +59,7 @@ func Test_env_and_args(t *testing.T) { t.Errorf("ParseSwitches: InputFile incorrect: %v\n", ea.InputFile) } + //iam: this test assumes LLVMToolChainBinDir = "" checkExecutables(t, ea, "llvm-link", "llvm-ar", "ar", "clang", "clang++") os.Setenv("LLVM_COMPILER_PATH", "/the_future_is_here") @@ -81,5 +89,4 @@ func Test_env_and_args(t *testing.T) { "ar", "/the_future_is_here/clang-666", "/the_future_is_here/clang++-666") - }