diff --git a/README.md b/README.md index 8861912..4805add 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,12 @@ bitcode in parallel, and is faster. A comparison between the two tools can be gl |-----------------------------|-----------------------------| | wllvm | gclang | | wllvm++ | gclang++ | +| | gflang | | extract-bc | get-bc | | wllvm-sanity-checker | gsanity-check | | LLVM_COMPILER_PATH | LLVM_COMPILER_PATH | | LLVM_CC_NAME ... | LLVM_CC_NAME ... | +| | LLVM_F_NAME | | WLLVM_CONFIGURE_ONLY | WLLVM_CONFIGURE_ONLY | | WLLVM_OUTPUT_LEVEL | WLLVM_OUTPUT_LEVEL | | WLLVM_OUTPUT_FILE | WLLVM_OUTPUT_FILE | @@ -52,7 +54,7 @@ For more details see [wllvm](https://github.com/SRI-CSL/whole-program-llvm). To install `gllvm` you need the go language [tool](https://golang.org/doc/install). -To use `gllvm` you need clang/clang++ and the llvm tools llvm-link and llvm-ar. +To use `gllvm` you need clang/clang++/flang and the llvm tools llvm-link and llvm-ar. `gllvm` is agnostic to the actual llvm version. `gllvm` also relies on standard build tools such as `objcopy` and `ld`. @@ -63,7 +65,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` +This should install five binaries: `gclang`, `gclang++`, `gflang`, `get-bc`, and `gsanity-check` in the `$GOPATH/bin` directory. If you are using `go 1.16` you may be forced to install it like this: @@ -74,7 +76,9 @@ Hopefully we will have a better fix for this [soon](https://github.com/golang/go ## Usage `gclang` and -`gclang++` are the wrappers used to compile C and C++. `get-bc` is used for +`gclang++` are the wrappers used to compile C and C++. +`gflang` is the wrapper used to compile Fortran. +`get-bc` is used for extracting the bitcode from a build product (either an object file, executable, library or archive). `gsanity-check` can be used for detecting configuration errors. @@ -106,8 +110,8 @@ environment variables. contains the compiler and the other LLVM tools to be used. * `LLVM_CC_NAME` can be set if your clang compiler is not called `clang` but - something like `clang-3.7`. Similarly `LLVM_CXX_NAME` can be used to - describe what the C++ compiler is called. We also pay attention to the + something like `clang-3.7`. Similarly `LLVM_CXX_NAME` and `LLVM_F_NAME` can be used to + describe what the C++ and Fortran compilers are called, respectively. We also pay attention to the environment variables `LLVM_LINK_NAME` and `LLVM_AR_NAME` in an analogous way. @@ -263,7 +267,7 @@ This will at least preserve the bitcode files, even if `get-bc` will not be able Debugging usually boils down to looking in the logs, maybe adding a print statement or two. There is an additional executable, not mentioned above, called `gparse` that gets installed -along with `gclang`, `gclang++`, `get-bc` and `gsanity-check`. `gparse` takes the command line +along with `gclang`, `gclang++`, `gflang`, `get-bc` and `gsanity-check`. `gparse` takes the command line arguments to the compiler, and outputs how it parsed them. This can sometimes be helpful. ## License diff --git a/cmd/gflang/main.go b/cmd/gflang/main.go new file mode 100644 index 0000000..3d1c322 --- /dev/null +++ b/cmd/gflang/main.go @@ -0,0 +1,54 @@ +// +// 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 ( + "github.com/SRI-CSL/gllvm/shared" + "os" +) + +func main() { + shared.LogInfo("Entering fortran %v\n", os.Args[1:]) + // Parse command line + args := os.Args + args = args[1:] + + exitCode := shared.Compile(args, "flang") + + shared.LogDebug("Calling %v returned %v\n", os.Args, exitCode) + + //important to pretend to look like the actual wrapped command + os.Exit(exitCode) + +} diff --git a/shared/compiler.go b/shared/compiler.go index cd01162..a64db2c 100644 --- a/shared/compiler.go +++ b/shared/compiler.go @@ -385,6 +385,11 @@ func GetCompilerExecName(compiler string) string { return filepath.Join(LLVMToolChainBinDir, LLVMCXXName) } return filepath.Join(LLVMToolChainBinDir, compiler) + case "flang": + if LLVMFName != "" { + return filepath.Join(LLVMToolChainBinDir, LLVMCCName) + } + return filepath.Join(LLVMToolChainBinDir, compiler) default: LogError("The compiler %s is not supported by this tool.", compiler) return "" diff --git a/shared/environment.go b/shared/environment.go index 8aa00ec..2903458 100644 --- a/shared/environment.go +++ b/shared/environment.go @@ -59,6 +59,9 @@ var LLVMCCName string //LLVMCXXName is the user configured name of the clang++ compiler. var LLVMCXXName string +//LLVMFName is the user configered name of the flang compiler. +var LLVMFName string + //LLVMARName is the user configured name of the llvm-ar. var LLVMARName string @@ -93,6 +96,7 @@ const ( envpath = "LLVM_COMPILER_PATH" envcc = "LLVM_CC_NAME" envcxx = "LLVM_CXX_NAME" + envf = "LLVM_F_NAME" envar = "LLVM_AR_NAME" envlnk = "LLVM_LINK_NAME" envcfg = "WLLVM_CONFIGURE_ONLY" @@ -116,7 +120,7 @@ func init() { // PrintEnvironment is used for printing the aspects of the environment that concern us func PrintEnvironment() { - vars := []string{envpath, envcc, envcxx, envar, envlnk, envcfg, envbc, envlvl, envfile, envobjcopy, envld, envbcgen, envltolink} + vars := []string{envpath, envcc, envcxx, envf, envar, envlnk, envcfg, envbc, envlvl, envfile, envobjcopy, envld, envbcgen, envltolink} informUser("\nLiving in this environment:\n\n") for _, v := range vars { @@ -135,6 +139,7 @@ func ResetEnvironment() { LLVMToolChainBinDir = "" LLVMCCName = "" LLVMCXXName = "" + LLVMFName = "" LLVMARName = "" LLVMLINKName = "" LLVMConfigureOnly = "" @@ -152,6 +157,7 @@ func FetchEnvironment() { LLVMToolChainBinDir = os.Getenv(envpath) LLVMCCName = os.Getenv(envcc) LLVMCXXName = os.Getenv(envcxx) + LLVMFName = os.Getenv(envf) LLVMARName = os.Getenv(envar) LLVMLINKName = os.Getenv(envlnk) diff --git a/shared/sanity.go b/shared/sanity.go index 3e8b10b..10f1e75 100644 --- a/shared/sanity.go +++ b/shared/sanity.go @@ -59,6 +59,14 @@ then you will need to set the environment variable LLVM_CXX_NAME to the appropriate string. For example if your clang++ is called ++clang then LLVM_CC_NAME should be set to ++clang. +` +const explainLLVMFNAME = ` + +If your flang compiler is not called flang, but something else, +then you will need to set the environment variable LLVM_F_NAME to +the appropriate string. For example if your flang is called flang-7 +then LLVM_F_NAME should be set to flang-7. + ` const explainLLVMCOMPILERPATH = ` @@ -170,16 +178,26 @@ func checkCompilers() bool { cxx := GetCompilerExecName("clang++") cxxOK, cxxVersion, _ := checkExecutable(cxx, "-v") - if !ccOK { + if !cxxOK { informUser("The CXX compiler %s was not found or not executable.\nBetter not try using gclang++!\n", cxx) informUser(explainLLVMCOMPILERPATH) informUser(explainLLVMCXXNAME) } else { informUser("The CXX compiler %s is:\n\n\t%s\n\n", cxx, extractLine(cxxVersion, 0)) } + f := GetCompilerExecName("flang") + fOK, fVersion, _ := checkExecutable(f, "-v") + if !fOK { + informUser("The Fortran compiler %s was not found or not executable.\nBetter not try using gflang!\n", f) + informUser(explainLLVMCOMPILERPATH) + informUser(explainLLVMFNAME) + } else { + informUser("The Fortran compiler %s is:\n\n\t%s\n\n", f, extractLine(fVersion, 0)) + } + //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 || fOK } func extractLine(version string, n int) string {