2021-09-14 15:03:59 +08:00
|
|
|
import * as core from "@actions/core"
|
2021-09-16 16:26:53 +08:00
|
|
|
import { setupBrew } from "./brew/brew"
|
2021-09-16 16:41:47 +08:00
|
|
|
import { setupCcache } from "./ccache/ccache"
|
2022-01-31 06:40:11 +08:00
|
|
|
import { setupMake } from "./make/make"
|
2022-01-31 07:33:48 +08:00
|
|
|
import { setupTask } from "./task/task"
|
2021-09-15 05:01:08 +08:00
|
|
|
import { setupChocolatey } from "./chocolatey/chocolatey"
|
2021-09-14 15:33:49 +08:00
|
|
|
import { setupCmake } from "./cmake/cmake"
|
2021-09-15 01:06:20 +08:00
|
|
|
import { setupConan } from "./conan/conan"
|
2021-09-16 16:47:47 +08:00
|
|
|
import { setupCppcheck } from "./cppcheck/cppcheck"
|
|
|
|
import { setupDoxygen } from "./doxygen/doxygen"
|
2021-09-15 01:42:08 +08:00
|
|
|
import { setupGcovr } from "./gcovr/gcovr"
|
2022-01-30 06:44:43 +08:00
|
|
|
import { setupLLVM, setupClangTools } from "./llvm/llvm"
|
2021-09-15 01:09:58 +08:00
|
|
|
import { setupMeson } from "./meson/meson"
|
2021-09-15 18:25:02 +08:00
|
|
|
import { setupMSVC } from "./msvc/msvc"
|
2021-09-14 15:42:17 +08:00
|
|
|
import { setupNinja } from "./ninja/ninja"
|
2021-09-16 16:49:25 +08:00
|
|
|
import { setupOpencppcoverage } from "./opencppcoverage/opencppcoverage"
|
2021-09-15 04:23:45 +08:00
|
|
|
import { setupPython } from "./python/python"
|
2021-09-18 01:51:59 +08:00
|
|
|
import mri from "mri"
|
2022-01-20 03:58:10 +08:00
|
|
|
import { untildify_user as untildify } from "./utils/path/untildify"
|
2022-01-18 06:23:33 +08:00
|
|
|
import { isGitHubCI } from "./utils/env/isci"
|
2021-09-16 19:57:37 +08:00
|
|
|
|
2021-09-16 19:07:52 +08:00
|
|
|
import semverValid from "semver/functions/valid"
|
2021-09-16 19:36:35 +08:00
|
|
|
import { getVersion } from "./default_versions"
|
2021-09-16 22:03:54 +08:00
|
|
|
import { setupGcc } from "./gcc/gcc"
|
2021-09-18 01:51:59 +08:00
|
|
|
import { InstallationInfo } from "./utils/setup/setupBin"
|
2022-01-30 07:13:52 +08:00
|
|
|
import { error, success, warning } from "./utils/io/io"
|
2021-11-22 00:49:22 +08:00
|
|
|
import { setupVcpkg } from "./vcpkg/vcpkg"
|
2021-11-22 02:46:34 +08:00
|
|
|
import { join } from "path"
|
2021-12-05 22:20:14 +08:00
|
|
|
import { setupVCVarsall } from "./vcvarsall/vcvarsall"
|
2021-12-07 19:30:33 +08:00
|
|
|
import { setupKcov } from "./kcov/kcov"
|
2022-01-18 10:30:02 +08:00
|
|
|
import { addEnv } from "./utils/env/addEnv"
|
2022-02-06 12:20:36 +08:00
|
|
|
import { setupSevenZip } from "./sevenzip/sevenzip"
|
2022-02-14 07:50:15 +08:00
|
|
|
import { endGroup, startGroup } from "@actions/core"
|
2022-02-14 11:30:41 +08:00
|
|
|
import { setupGraphviz } from "./graphviz/graphviz"
|
2021-09-16 22:03:54 +08:00
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
/** The setup functions */
|
2021-09-18 01:12:33 +08:00
|
|
|
const setups = {
|
|
|
|
cmake: setupCmake,
|
|
|
|
ninja: setupNinja,
|
|
|
|
python: setupPython,
|
2021-11-22 00:49:22 +08:00
|
|
|
vcpkg: setupVcpkg,
|
2021-09-18 01:12:33 +08:00
|
|
|
conan: setupConan,
|
|
|
|
meson: setupMeson,
|
|
|
|
gcovr: setupGcovr,
|
|
|
|
opencppcoverage: setupOpencppcoverage,
|
|
|
|
llvm: setupLLVM,
|
|
|
|
gcc: setupGcc,
|
|
|
|
choco: setupChocolatey,
|
|
|
|
brew: setupBrew,
|
|
|
|
ccache: setupCcache,
|
|
|
|
doxygen: setupDoxygen,
|
2022-02-14 11:30:41 +08:00
|
|
|
graphviz: setupGraphviz,
|
2021-09-18 01:12:33 +08:00
|
|
|
cppcheck: setupCppcheck,
|
2022-01-30 06:44:43 +08:00
|
|
|
clangtidy: setupClangTools,
|
|
|
|
clangformat: setupClangTools,
|
2021-09-18 01:12:33 +08:00
|
|
|
msvc: setupMSVC,
|
2021-12-05 22:20:14 +08:00
|
|
|
vcvarsall: setupVCVarsall,
|
2021-12-07 19:30:33 +08:00
|
|
|
kcov: setupKcov,
|
2022-01-31 06:40:11 +08:00
|
|
|
make: setupMake,
|
2022-01-31 07:33:48 +08:00
|
|
|
task: setupTask,
|
2022-02-06 12:20:36 +08:00
|
|
|
sevenzip: setupSevenZip,
|
2021-09-18 01:12:33 +08:00
|
|
|
}
|
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
/** The tools that can be installed */
|
2021-09-18 01:12:33 +08:00
|
|
|
const tools: Array<keyof typeof setups> = [
|
2021-09-18 20:41:02 +08:00
|
|
|
"choco",
|
|
|
|
"brew",
|
|
|
|
"python",
|
2021-11-22 00:49:22 +08:00
|
|
|
"vcpkg",
|
2021-09-16 22:03:54 +08:00
|
|
|
"cmake",
|
|
|
|
"ninja",
|
|
|
|
"conan",
|
|
|
|
"meson",
|
|
|
|
"gcovr",
|
|
|
|
"opencppcoverage",
|
|
|
|
"ccache",
|
|
|
|
"doxygen",
|
2022-02-14 11:30:41 +08:00
|
|
|
"graphviz",
|
2021-09-16 22:03:54 +08:00
|
|
|
"cppcheck",
|
2022-01-30 06:44:43 +08:00
|
|
|
"clangtidy",
|
|
|
|
"clangformat",
|
2021-09-18 20:41:02 +08:00
|
|
|
"llvm",
|
|
|
|
"gcc",
|
2021-09-16 22:03:54 +08:00
|
|
|
"msvc",
|
2021-12-05 22:20:14 +08:00
|
|
|
"vcvarsall",
|
2021-12-07 19:30:33 +08:00
|
|
|
"kcov",
|
2022-01-31 06:40:11 +08:00
|
|
|
"make",
|
2022-01-31 07:33:48 +08:00
|
|
|
"task",
|
2022-02-06 12:20:36 +08:00
|
|
|
"sevenzip",
|
2021-09-16 22:03:54 +08:00
|
|
|
]
|
2021-09-16 19:57:37 +08:00
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
/** The possible inputs to the program */
|
|
|
|
type Inputs = keyof typeof setups | "compiler" | "architecture"
|
2021-09-14 15:42:17 +08:00
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
// an array of possible inputs
|
|
|
|
const inputs: Array<Inputs> = ["compiler", "architecture", ...tools]
|
|
|
|
|
|
|
|
/** The main entry function */
|
|
|
|
export async function main(args: string[]): Promise<number> {
|
2022-01-18 06:23:33 +08:00
|
|
|
if (!isGitHubCI()) {
|
2021-09-18 20:20:18 +08:00
|
|
|
process.env.ACTIONS_ALLOW_UNSECURE_COMMANDS = "true"
|
|
|
|
}
|
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
// parse options using mri or github actions
|
2021-09-18 02:09:00 +08:00
|
|
|
const opts = mri<Record<Inputs, string | undefined> & { help: boolean }>(args, {
|
2021-09-18 01:51:59 +08:00
|
|
|
string: inputs,
|
|
|
|
default: Object.fromEntries(inputs.map((inp) => [inp, maybeGetInput(inp)])),
|
2021-09-18 02:09:00 +08:00
|
|
|
alias: { h: "help" },
|
|
|
|
boolean: "help",
|
2021-09-18 01:51:59 +08:00
|
|
|
})
|
2021-09-14 15:03:59 +08:00
|
|
|
|
2021-09-18 02:09:00 +08:00
|
|
|
// print help
|
|
|
|
if (opts.help) {
|
|
|
|
printHelp()
|
|
|
|
}
|
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
// cpu architecture
|
|
|
|
const arch = opts.architecture ?? process.arch
|
|
|
|
|
|
|
|
// the installation dir for the tools that are downloaded directly
|
2022-01-20 03:58:10 +08:00
|
|
|
const setupCppDir = process.env.SETUP_CPP_DIR ?? untildify("")
|
2021-09-18 01:51:59 +08:00
|
|
|
|
|
|
|
// report messages
|
|
|
|
const successMessages: string[] = []
|
|
|
|
const errorMessages: string[] = []
|
|
|
|
|
2021-09-18 20:44:12 +08:00
|
|
|
// installing the specified tools
|
|
|
|
|
|
|
|
// loop over the tools and run their setup function
|
|
|
|
for (const tool of tools) {
|
|
|
|
// get the version or "true" or undefined for this tool from the options
|
2022-02-14 07:50:15 +08:00
|
|
|
const version = opts[tool]
|
2021-09-18 20:44:12 +08:00
|
|
|
|
|
|
|
// skip if undefined
|
2022-02-14 07:50:15 +08:00
|
|
|
if (version !== undefined) {
|
2021-11-22 04:20:51 +08:00
|
|
|
// running the setup function for this tool
|
2022-02-14 07:50:15 +08:00
|
|
|
startGroup(`Installing ${tool} ${version}`)
|
2021-09-18 20:44:12 +08:00
|
|
|
try {
|
2021-12-05 22:20:14 +08:00
|
|
|
let installationInfo: InstallationInfo | undefined | void
|
|
|
|
if (tool === "vcvarsall") {
|
|
|
|
// eslint-disable-next-line no-await-in-loop
|
2022-02-14 07:50:15 +08:00
|
|
|
setupVCVarsall(getVersion(tool, version), undefined, arch, undefined, undefined, false, false)
|
2021-12-05 22:20:14 +08:00
|
|
|
} else {
|
2021-12-06 21:11:58 +08:00
|
|
|
// get the setup function
|
|
|
|
const setupFunction = setups[tool]
|
|
|
|
|
2021-12-05 22:20:14 +08:00
|
|
|
// eslint-disable-next-line no-await-in-loop
|
2022-02-14 07:50:15 +08:00
|
|
|
installationInfo = await setupFunction(getVersion(tool, version), join(setupCppDir, tool), arch)
|
2021-12-05 22:20:14 +08:00
|
|
|
}
|
2021-09-18 20:44:12 +08:00
|
|
|
// preparing a report string
|
2022-01-30 07:13:52 +08:00
|
|
|
successMessages.push(getSuccessMessage(tool, installationInfo))
|
2021-09-18 20:44:12 +08:00
|
|
|
} catch (e) {
|
|
|
|
// push error message to the logger
|
2021-09-18 21:21:22 +08:00
|
|
|
error(e as string | Error)
|
2021-09-18 20:44:12 +08:00
|
|
|
errorMessages.push(`${tool} failed to install`)
|
|
|
|
}
|
2022-02-14 07:50:15 +08:00
|
|
|
endGroup()
|
2021-09-18 20:44:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
// installing the specified compiler
|
|
|
|
const maybeCompiler = opts.compiler
|
2021-09-14 15:03:59 +08:00
|
|
|
try {
|
2021-09-16 19:07:52 +08:00
|
|
|
if (maybeCompiler !== undefined) {
|
2021-11-22 06:40:30 +08:00
|
|
|
const { compiler, version } = getCompilerInfo(maybeCompiler)
|
2021-09-16 19:07:52 +08:00
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
// install the compiler. We allow some aliases for the compiler name
|
2022-02-14 07:50:15 +08:00
|
|
|
startGroup(`Installing ${compiler} ${version ?? ""}`)
|
2021-09-16 19:07:52 +08:00
|
|
|
switch (compiler) {
|
|
|
|
case "llvm":
|
|
|
|
case "clang":
|
|
|
|
case "clang++": {
|
2022-02-02 12:19:46 +08:00
|
|
|
const installationInfo = await setupLLVM(getVersion("llvm", version), join(setupCppDir, "llvm"), arch)
|
2022-01-30 07:13:52 +08:00
|
|
|
successMessages.push(getSuccessMessage("llvm", installationInfo))
|
2021-09-16 19:07:52 +08:00
|
|
|
break
|
|
|
|
}
|
2021-09-16 22:03:54 +08:00
|
|
|
case "gcc":
|
|
|
|
case "mingw":
|
|
|
|
case "cygwin":
|
|
|
|
case "msys": {
|
2022-02-02 12:19:46 +08:00
|
|
|
const installationInfo = await setupGcc(getVersion("gcc", version), join(setupCppDir, "gcc"), arch)
|
2022-01-30 07:13:52 +08:00
|
|
|
successMessages.push(getSuccessMessage("gcc", installationInfo))
|
2021-09-16 22:03:54 +08:00
|
|
|
break
|
|
|
|
}
|
2021-09-16 19:07:52 +08:00
|
|
|
case "cl":
|
|
|
|
case "msvc":
|
|
|
|
case "msbuild":
|
|
|
|
case "vs":
|
|
|
|
case "visualstudio":
|
|
|
|
case "visualcpp":
|
|
|
|
case "visualc++": {
|
2022-02-02 12:19:46 +08:00
|
|
|
const installationInfo = setupMSVC(getVersion("msvc", version), join(setupCppDir, "msvc"), arch)
|
2022-01-30 07:13:52 +08:00
|
|
|
successMessages.push(getSuccessMessage("msvc", installationInfo))
|
2021-09-16 19:07:52 +08:00
|
|
|
break
|
|
|
|
}
|
2021-12-07 17:01:13 +08:00
|
|
|
case "appleclang":
|
|
|
|
case "applellvm": {
|
2021-12-08 03:11:52 +08:00
|
|
|
core.info("Assuming apple-clang is already installed")
|
2022-01-18 10:30:02 +08:00
|
|
|
addEnv("CC", "clang")
|
|
|
|
addEnv("CXX", "clang++")
|
2022-01-30 07:13:52 +08:00
|
|
|
successMessages.push(getSuccessMessage("apple-clang", undefined))
|
2021-12-07 17:01:13 +08:00
|
|
|
break
|
|
|
|
}
|
2021-09-16 19:07:52 +08:00
|
|
|
default: {
|
2021-09-18 01:51:59 +08:00
|
|
|
errorMessages.push(`Unsupported compiler ${compiler}`)
|
2021-09-16 19:07:52 +08:00
|
|
|
}
|
|
|
|
}
|
2022-02-14 07:50:15 +08:00
|
|
|
endGroup()
|
2021-09-16 19:07:52 +08:00
|
|
|
}
|
2021-09-18 01:51:59 +08:00
|
|
|
} catch (e) {
|
2021-09-18 21:21:22 +08:00
|
|
|
error(e as string | Error)
|
2021-09-18 01:51:59 +08:00
|
|
|
errorMessages.push(`Failed to install the ${maybeCompiler}`)
|
2022-02-14 07:50:15 +08:00
|
|
|
endGroup()
|
2021-09-18 01:51:59 +08:00
|
|
|
}
|
|
|
|
|
2022-01-30 07:13:52 +08:00
|
|
|
if (successMessages.length === 0 && errorMessages.length === 0) {
|
|
|
|
warning("setup_cpp was called without any arguments. Nothing to do.")
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
// report the messages in the end
|
2021-09-18 21:21:22 +08:00
|
|
|
successMessages.forEach((tool) => success(tool))
|
|
|
|
errorMessages.forEach((tool) => error(tool))
|
2021-09-18 01:51:59 +08:00
|
|
|
|
2021-09-18 02:19:10 +08:00
|
|
|
core.info("setup_cpp finished")
|
2021-09-30 08:51:50 +08:00
|
|
|
|
2022-01-18 06:23:33 +08:00
|
|
|
if (!isGitHubCI()) {
|
2021-09-30 08:51:50 +08:00
|
|
|
switch (process.platform) {
|
|
|
|
case "win32": {
|
|
|
|
core.info("Run `RefreshEnv.cmd` or restart your shell to update the environment.")
|
|
|
|
break
|
|
|
|
}
|
|
|
|
case "linux":
|
|
|
|
case "darwin": {
|
2022-03-01 18:43:50 +08:00
|
|
|
core.info("Run `source ~/.cpprc` or restart your shell to update the environment.")
|
2021-09-30 08:51:50 +08:00
|
|
|
break
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
// nothing
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
return errorMessages.length === 0 ? 0 : 1 // exit with non-zero if any error message
|
2021-09-14 15:03:59 +08:00
|
|
|
}
|
2021-09-18 01:51:59 +08:00
|
|
|
// Run main
|
|
|
|
main(process.argv)
|
2021-09-14 15:03:59 +08:00
|
|
|
.then((ret) => {
|
|
|
|
process.exitCode = ret
|
|
|
|
})
|
2021-09-18 21:21:22 +08:00
|
|
|
.catch((err) => {
|
|
|
|
error("main() panicked!")
|
|
|
|
error(err as string | Error)
|
2021-09-14 15:03:59 +08:00
|
|
|
process.exitCode = 1
|
|
|
|
})
|
2021-09-18 01:51:59 +08:00
|
|
|
|
2021-11-22 06:40:30 +08:00
|
|
|
/** Detecting the compiler version. Divide the given string by `-` and use the second element as the version */
|
|
|
|
export function getCompilerInfo(maybeCompiler: string) {
|
|
|
|
const compilerAndMaybeVersion = maybeCompiler.split("-")
|
|
|
|
const compiler = compilerAndMaybeVersion[0]
|
|
|
|
if (1 in compilerAndMaybeVersion) {
|
|
|
|
const maybeVersion = compilerAndMaybeVersion[1]
|
|
|
|
if (semverValid(maybeVersion) !== null) {
|
|
|
|
return { compiler, version: maybeVersion }
|
|
|
|
} else {
|
2021-12-08 03:11:52 +08:00
|
|
|
core.info(`Invalid semver version ${maybeVersion} used for the compiler.`)
|
2021-11-22 06:40:30 +08:00
|
|
|
return { compiler, version: maybeVersion }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return { compiler, version: undefined }
|
|
|
|
}
|
|
|
|
|
2021-09-18 02:09:00 +08:00
|
|
|
function printHelp() {
|
|
|
|
core.info(`
|
2021-09-18 02:19:10 +08:00
|
|
|
setup_cpp [options]
|
2021-11-22 02:46:34 +08:00
|
|
|
setup_cpp --compiler llvm --cmake true --ninja true --ccache true --vcpkg true
|
2021-09-18 02:09:00 +08:00
|
|
|
|
|
|
|
Install all the tools required for building and testing C++/C projects.
|
|
|
|
|
|
|
|
--architecture\t the cpu architecture to install the tools for. By default it uses the current CPU architecture.
|
|
|
|
--compiler\t the <compiler> to install.
|
2021-11-22 06:40:30 +08:00
|
|
|
\t You can specify the version instead of specifying just the name e.g: --compiler 'llvm-13.0.0'
|
2021-09-18 02:09:00 +08:00
|
|
|
|
2021-11-22 02:46:34 +08:00
|
|
|
--tool_name\t pass "true" or pass the <version> you would like to install for this tool. e.g. --conan true or --conan "1.42.1"
|
2021-09-18 02:09:00 +08:00
|
|
|
|
|
|
|
All the available tools:
|
|
|
|
--llvm
|
|
|
|
--gcc
|
2021-12-05 22:20:14 +08:00
|
|
|
--vcvarsall
|
2021-09-18 02:09:00 +08:00
|
|
|
--cmake
|
|
|
|
--ninja
|
2021-11-22 00:49:22 +08:00
|
|
|
--vcpkg
|
2021-09-18 02:09:00 +08:00
|
|
|
--meson
|
|
|
|
--conan
|
2022-01-31 06:40:11 +08:00
|
|
|
--make
|
2022-01-31 07:38:33 +08:00
|
|
|
--task
|
2021-09-18 02:09:00 +08:00
|
|
|
--ccache
|
|
|
|
--cppcheck
|
2022-01-30 06:44:43 +08:00
|
|
|
--clangformat
|
|
|
|
--clangtidy
|
2021-09-18 02:09:00 +08:00
|
|
|
--doxygen
|
|
|
|
--gcovr
|
|
|
|
--opencppcoverage
|
2021-12-07 19:30:33 +08:00
|
|
|
--kcov
|
2022-02-06 12:20:36 +08:00
|
|
|
|
2021-09-18 02:09:00 +08:00
|
|
|
--python
|
|
|
|
--choco
|
|
|
|
--brew
|
2022-02-06 12:20:36 +08:00
|
|
|
--sevenzip
|
2022-02-14 11:30:41 +08:00
|
|
|
--graphviz
|
2021-09-18 02:09:00 +08:00
|
|
|
`)
|
|
|
|
}
|
|
|
|
|
2021-09-18 01:51:59 +08:00
|
|
|
/** Get an object from github actions */
|
|
|
|
function maybeGetInput(key: string) {
|
|
|
|
const value = core.getInput(key.toLowerCase())
|
|
|
|
if (value !== "false" && value !== "") {
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
return undefined // skip installation
|
|
|
|
}
|
|
|
|
|
2022-01-30 07:13:52 +08:00
|
|
|
function getSuccessMessage(tool: string, installationInfo: InstallationInfo | undefined | void) {
|
2021-09-18 21:21:22 +08:00
|
|
|
let msg = `${tool} was successfully installed`
|
2022-01-30 07:13:52 +08:00
|
|
|
if (installationInfo === undefined) {
|
|
|
|
return msg
|
|
|
|
}
|
2021-09-18 01:51:59 +08:00
|
|
|
if ("installDir" in installationInfo) {
|
2021-11-22 04:20:51 +08:00
|
|
|
msg += `\nThe installation directory is ${installationInfo.installDir}`
|
2021-09-18 01:51:59 +08:00
|
|
|
}
|
|
|
|
if (installationInfo.binDir !== "") {
|
2021-11-22 04:20:51 +08:00
|
|
|
msg += `\nThe binary directory is ${installationInfo.binDir}`
|
2021-09-18 01:51:59 +08:00
|
|
|
}
|
2021-09-18 21:21:22 +08:00
|
|
|
return msg
|
2021-09-18 01:51:59 +08:00
|
|
|
}
|