Quellcode durchsuchen

improve llvm to support libraries (#1807)

* improve llvm to support libraries

* improve llvm fetch
ruki vor 2 Jahren
Ursprung
Commit
8fc3e5632a

+ 138 - 0
packages/l/llvm/components/base.lua

@@ -0,0 +1,138 @@
+function get_links(package)
+    local links = {
+        "LLVMAggressiveInstCombine",
+        "LLVMAnalysis",
+        "LLVMAsmParser",
+        "LLVMAsmPrinter",
+        "LLVMBinaryFormat",
+        "LLVMBitReader",
+        "LLVMBitWriter",
+        "LLVMBitstreamReader",
+        "LLVMCFGuard",
+        "LLVMCFIVerify",
+        "LLVMCodeGen",
+        "LLVMCore",
+        "LLVMCoroutines",
+        "LLVMCoverage",
+        "LLVMDWARFLinker",
+        "LLVMDWP",
+        "LLVMDebugInfoCodeView",
+        "LLVMDebugInfoDWARF",
+        "LLVMDebugInfoGSYM",
+        "LLVMDebugInfoMSF",
+        "LLVMDebugInfoPDB",
+        "LLVMDebuginfod",
+        "LLVMDemangle",
+        "LLVMDiff",
+        "LLVMDlltoolDriver",
+        "LLVMExecutionEngine",
+        "LLVMExegesis",
+        "LLVMExtensions",
+        "LLVMFileCheck",
+        "LLVMFrontendOpenACC",
+        "LLVMFrontendOpenMP",
+        "LLVMFuzzMutate",
+        "LLVMGlobalISel",
+        "LLVMIRReader",
+        "LLVMInstCombine",
+        "LLVMInstrumentation",
+        "LLVMInterfaceStub",
+        "LLVMInterpreter",
+        "LLVMJITLink",
+        "LLVMLTO",
+        "LLVMLibDriver",
+        "LLVMLineEditor",
+        "LLVMLinker",
+        "LLVMMC",
+        "LLVMMCA",
+        "LLVMMCDisassembler",
+        "LLVMMCJIT",
+        "LLVMMCParser",
+        "LLVMMIRParser",
+        "LLVMObjCARCOpts",
+        "LLVMObject",
+        "LLVMObjectYAML",
+        "LLVMOption",
+        "LLVMOrcJIT",
+        "LLVMOrcShared",
+        "LLVMOrcTargetProcess",
+        "LLVMPasses",
+        "LLVMProfileData",
+        "LLVMRemarks",
+        "LLVMRuntimeDyld",
+        "LLVMScalarOpts",
+        "LLVMSelectionDAG",
+        "LLVMSupport",
+        "LLVMSymbolize",
+        "LLVMTableGen",
+        "LLVMTableGenGlobalISel",
+        "LLVMTarget",
+        "LLVMTextAPI",
+        "LLVMTransformUtils",
+        "LLVMVectorize",
+        "LLVMWindowsManifest",
+        "LLVMXRay",
+        "LLVMipo"
+    }
+    local links_arch
+    if package:is_arch("x86_64", "i386", "x64", "x86") then
+        links_arch = {
+            "LLVMX86AsmParser",
+            "LLVMX86CodeGen",
+            "LLVMX86Desc",
+            "LLVMX86Disassembler",
+            "LLVMX86Info",
+            "LLVMX86TargetMCA",
+            "LLVMExegesisX86"}
+    elseif package:is_arch("arm64") then
+        links_arch = {
+            "LLVMAArch64AsmParser",
+            "LLVMAArch64CodeGen",
+            "LLVMAArch64Desc",
+            "LLVMAArch64Disassembler",
+            "LLVMAArch64Info",
+            "LLVMAArch64Utils",
+            "LLVMExegesisAArch64"}
+    elseif package:is_arch("armv7") then
+        links_arch = {
+            "LLVMARMAsmParser",
+            "LLVMARMCodeGen",
+            "LLVMARMDesc",
+            "LLVMARMDisassembler",
+            "LLVMARMInfo",
+            "LLVMARMUtils"}
+    elseif package:is_arch("mips", "mips64") then
+        links_arch = {
+            "LLVMMipsAsmParser",
+            "LLVMMipsCodeGen",
+            "LLVMMipsDesc",
+            "LLVMMipsDisassembler",
+            "LLVMMipsInfo",
+            "LLVMExegesisMips"}
+    elseif package:is_arch("wasm32") then
+        links_arch = {
+            "LLVMWebAssemblyAsmParser",
+            "LLVMWebAssemblyCodeGen",
+            "LLVMWebAssemblyDesc",
+            "LLVMWebAssemblyDisassembler",
+            "LLVMWebAssemblyInfo",
+            "LLVMWebAssemblyUtils"}
+    elseif package:is_arch("riscv32") then
+        links_arch = {
+            "LLVMRISCVAsmParser",
+            "LLVMRISCVCodeGen",
+            "LLVMRISCVDesc",
+            "LLVMRISCVDisassembler",
+            "LLVMRISCVInfo"}
+    end
+    if links_arch then
+        table.join2(links, links_arch)
+    end
+    return links
+end
+
+function main(package, component)
+    component:add("links", get_links(package))
+end
+
+

+ 94 - 0
packages/l/llvm/components/clang.lua

@@ -0,0 +1,94 @@
+function get_links(package)
+    local links = {
+        "clang-cpp",
+        "clang",
+        "clangAPINotes",
+        "clangARCMigrate",
+        "clangAST",
+        "clangASTMatchers",
+        "clangAnalysis",
+        "clangAnalysisFlowSensitive",
+        "clangApplyReplacements",
+        "clangBasic",
+        "clangChangeNamespace",
+        "clangCodeGen",
+        "clangCrossTU",
+        "clangDaemon",
+        "clangDaemonTweaks",
+        "clangDependencyScanning",
+        "clangDirectoryWatcher",
+        "clangDoc",
+        "clangDriver",
+        "clangDynamicASTMatchers",
+        "clangEdit",
+        "clangFormat",
+        "clangFrontend",
+        "clangFrontendTool",
+        "clangHandleCXX",
+        "clangHandleLLVM",
+        "clangIncludeFixer",
+        "clangIncludeFixerPlugin",
+        "clangIndex",
+        "clangIndexSerialization",
+        "clangInterpreter",
+        "clangLex",
+        "clangMove",
+        "clangParse",
+        "clangQuery",
+        "clangReorderFields",
+        "clangRewrite",
+        "clangRewriteFrontend",
+        "clangSema",
+        "clangSerialization",
+        "clangStaticAnalyzerCheckers",
+        "clangStaticAnalyzerCore",
+        "clangStaticAnalyzerFrontend",
+        "clangTesting",
+        "clangTidy",
+        "clangTidyAbseilModule",
+        "clangTidyAlteraModule",
+        "clangTidyAndroidModule",
+        "clangTidyBoostModule",
+        "clangTidyBugproneModule",
+        "clangTidyCERTModule",
+        "clangTidyConcurrencyModule",
+        "clangTidyCppCoreGuidelinesModule",
+        "clangTidyDarwinModule",
+        "clangTidyFuchsiaModule",
+        "clangTidyGoogleModule",
+        "clangTidyHICPPModule",
+        "clangTidyLLVMLibcModule",
+        "clangTidyLLVMModule",
+        "clangTidyLinuxKernelModule",
+        "clangTidyMPIModule",
+        "clangTidyMain",
+        "clangTidyMiscModule",
+        "clangTidyModernizeModule",
+        "clangTidyObjCModule",
+        "clangTidyOpenMPModule",
+        "clangTidyPerformanceModule",
+        "clangTidyPlugin",
+        "clangTidyPortabilityModule",
+        "clangTidyReadabilityModule",
+        "clangTidyUtils",
+        "clangTidyZirconModule",
+        "clangTooling",
+        "clangToolingASTDiff",
+        "clangToolingCore",
+        "clangToolingInclusions",
+        "clangToolingRefactoring",
+        "clangToolingSyntax",
+        "clangTransformer",
+        "clangdRemoteIndex",
+        "clangdSupport",
+        "clangdXpcJsonConversions",
+        "clangdXpcTransport"
+    }
+    return links
+end
+
+function main(package, component)
+    component:add("links", get_links(package))
+end
+
+

+ 12 - 0
packages/l/llvm/components/libunwind.lua

@@ -0,0 +1,12 @@
+function get_links(package)
+    local links = {
+        "unwind"
+    }
+    return links
+end
+
+function main(package, component)
+    component:add("links", get_links(package))
+end
+
+

+ 223 - 0
packages/l/llvm/components/mlir.lua

@@ -0,0 +1,223 @@
+function get_links(package)
+    local links = {
+        "MLIRAMX",
+        "MLIRAMXToLLVMIRTranslation",
+        "MLIRAMXTransforms",
+        "MLIRAffine",
+        "MLIRAffineAnalysis",
+        "MLIRAffineBufferizableOpInterfaceImpl",
+        "MLIRAffineToStandard",
+        "MLIRAffineTransforms",
+        "MLIRAffineTransformsTestPasses",
+        "MLIRAffineUtils",
+        "MLIRAnalysis",
+        "MLIRArithmetic",
+        "MLIRArithmeticToLLVM",
+        "MLIRArithmeticToSPIRV",
+        "MLIRArithmeticTransforms",
+        "MLIRAsync",
+        "MLIRAsyncToLLVM",
+        "MLIRAsyncTransforms",
+        "MLIRBufferization",
+        "MLIRBufferizationToMemRef",
+        "MLIRBufferizationTransforms",
+        "MLIRCAPIAsync",
+        "MLIRCAPIConversion",
+        "MLIRCAPIDebug",
+        "MLIRCAPIExecutionEngine",
+        "MLIRCAPIGPU",
+        "MLIRCAPIIR",
+        "MLIRCAPIInterfaces",
+        "MLIRCAPILLVM",
+        "MLIRCAPILinalg",
+        "MLIRCAPIPDL",
+        "MLIRCAPIQuant",
+        "MLIRCAPIRegistration",
+        "MLIRCAPISCF",
+        "MLIRCAPIShape",
+        "MLIRCAPISparseTensor",
+        "MLIRCAPIStandard",
+        "MLIRCAPITensor",
+        "MLIRCAPITransforms",
+        "MLIRCallInterfaces",
+        "MLIRCastInterfaces",
+        "MLIRComplex",
+        "MLIRComplexToLLVM",
+        "MLIRComplexToStandard",
+        "MLIRControlFlowInterfaces",
+        "MLIRCopyOpInterface",
+        "MLIRDLTI",
+        "MLIRDLTITestPasses",
+        "MLIRDataLayoutInterfaces",
+        "MLIRDerivedAttributeOpInterface",
+        "MLIRDialect",
+        "MLIRDialectUtils",
+        "MLIREmitC",
+        "MLIRExecutionEngine",
+        "MLIRGPUOps",
+        "MLIRGPUTestPasses",
+        "MLIRGPUToGPURuntimeTransforms",
+        "MLIRGPUToNVVMTransforms",
+        "MLIRGPUToROCDLTransforms",
+        "MLIRGPUToSPIRV",
+        "MLIRGPUToVulkanTransforms",
+        "MLIRGPUTransforms",
+        "MLIRIR",
+        "MLIRInferTypeOpInterface",
+        "MLIRJitRunner",
+        "MLIRLLVMCommonConversion",
+        "MLIRLLVMIR",
+        "MLIRLLVMIRTransforms",
+        "MLIRLLVMToLLVMIRTranslation",
+        "MLIRLinalg",
+        "MLIRLinalgAnalysis",
+        "MLIRLinalgBufferizableOpInterfaceImpl",
+        "MLIRLinalgTestPasses",
+        "MLIRLinalgToLLVM",
+        "MLIRLinalgToSPIRV",
+        "MLIRLinalgToStandard",
+        "MLIRLinalgTransforms",
+        "MLIRLinalgUtils",
+        "MLIRLoopLikeInterface",
+        "MLIRLspServerLib",
+        "MLIRMath",
+        "MLIRMathTestPasses",
+        "MLIRMathToLLVM",
+        "MLIRMathToLibm",
+        "MLIRMathToSPIRV",
+        "MLIRMathTransforms",
+        "MLIRMemRef",
+        "MLIRMemRefTestPasses",
+        "MLIRMemRefToLLVM",
+        "MLIRMemRefToSPIRV",
+        "MLIRMemRefTransforms",
+        "MLIRMemRefUtils",
+        "MLIRMlirOptMain",
+        "MLIRModuleBufferization",
+        "MLIRNVVMIR",
+        "MLIRNVVMToLLVMIRTranslation",
+        "MLIROpenACC",
+        "MLIROpenACCToLLVM",
+        "MLIROpenACCToLLVMIRTranslation",
+        "MLIROpenACCToSCF",
+        "MLIROpenMP",
+        "MLIROpenMPToLLVM",
+        "MLIROpenMPToLLVMIRTranslation",
+        "MLIROptLib",
+        "MLIRPDL",
+        "MLIRPDLInterp",
+        "MLIRPDLLAST",
+        "MLIRPDLLParser",
+        "MLIRPDLToPDLInterp",
+        "MLIRParser",
+        "MLIRPass",
+        "MLIRPresburger",
+        "MLIRQuant",
+        "MLIRROCDLIR",
+        "MLIRROCDLToLLVMIRTranslation",
+        "MLIRReconcileUnrealizedCasts",
+        "MLIRReduce",
+        "MLIRReduceLib",
+        "MLIRRewrite",
+        "MLIRSCF",
+        "MLIRSCFTestPasses",
+        "MLIRSCFToGPU",
+        "MLIRSCFToOpenMP",
+        "MLIRSCFToSPIRV",
+        "MLIRSCFToStandard",
+        "MLIRSCFTransforms",
+        "MLIRSCFUtils",
+        "MLIRSPIRV",
+        "MLIRSPIRVBinaryUtils",
+        "MLIRSPIRVConversion",
+        "MLIRSPIRVDeserialization",
+        "MLIRSPIRVModuleCombiner",
+        "MLIRSPIRVSerialization",
+        "MLIRSPIRVTestPasses",
+        "MLIRSPIRVToLLVM",
+        "MLIRSPIRVTransforms",
+        "MLIRSPIRVTranslateRegistration",
+        "MLIRSPIRVUtils",
+        "MLIRShape",
+        "MLIRShapeOpsTransforms",
+        "MLIRShapeTestPasses",
+        "MLIRShapeToStandard",
+        "MLIRSideEffectInterfaces",
+        "MLIRSparseTensor",
+        "MLIRSparseTensorPipelines",
+        "MLIRSparseTensorTransforms",
+        "MLIRSparseTensorUtils",
+        "MLIRStandard",
+        "MLIRStandardOpsTestPasses",
+        "MLIRStandardOpsTransforms",
+        "MLIRStandardToLLVM",
+        "MLIRStandardToSPIRV",
+        "MLIRSupport",
+        "MLIRSupportIndentedOstream",
+        "MLIRTableGen",
+        "MLIRTargetCpp",
+        "MLIRTargetLLVMIRExport",
+        "MLIRTargetLLVMIRImport",
+        "MLIRTensor",
+        "MLIRTensorInferTypeOpInterfaceImpl",
+        "MLIRTensorTilingInterfaceImpl",
+        "MLIRTensorTransforms",
+        "MLIRTensorUtils",
+        "MLIRTestAnalysis",
+        "MLIRTestDialect",
+        "MLIRTestIR",
+        "MLIRTestPass",
+        "MLIRTestReducer",
+        "MLIRTestRewrite",
+        "MLIRTestStandardToLLVM",
+        "MLIRTestTransforms",
+        "MLIRTilingInterface",
+        "MLIRToLLVMIRTranslationRegistration",
+        "MLIRTosa",
+        "MLIRTosaTestPasses",
+        "MLIRTosaToLinalg",
+        "MLIRTosaToSCF",
+        "MLIRTosaToStandard",
+        "MLIRTosaTransforms",
+        "MLIRTransformUtils",
+        "MLIRTransforms",
+        "MLIRTranslation",
+        "MLIRVector",
+        "MLIRVectorInterfaces",
+        "MLIRVectorTestPasses",
+        "MLIRVectorToGPU",
+        "MLIRVectorToLLVM",
+        "MLIRVectorToROCDL",
+        "MLIRVectorToSCF",
+        "MLIRVectorToSPIRV",
+        "MLIRVectorTransforms",
+        "MLIRVectorUtils",
+        "MLIRViewLikeInterface"
+    }
+
+    local links_arch
+    if package:is_arch("x86_64", "i386", "x64", "x86") then
+        links_arch = {
+            "MLIRX86Vector",
+            "MLIRX86VectorToLLVMIRTranslation",
+            "MLIRX86VectorTransforms"}
+    elseif package:is_arch("arm64", "armv7") then
+        links_arch = {
+            "MLIRArmNeon",
+            "MLIRArmNeon2dToIntr",
+            "MLIRArmNeonToLLVMIRTranslation",
+            "MLIRArmSVE",
+            "MLIRArmSVEToLLVMIRTranslation",
+            "MLIRArmSVETransforms"}
+    end
+    if links_arch then
+        table.join2(links, links_arch)
+    end
+    return links
+end
+
+function main(package, component)
+    component:add("links", get_links(package))
+end
+
+

+ 55 - 0
packages/l/llvm/fetch.lua

@@ -0,0 +1,55 @@
+import("lib.detect.find_tool")
+import("core.project.target")
+
+function main(package, opt)
+    if opt.system then
+        local llvm_config = "llvm-config"
+        if package:is_plat("macosx") then
+            local llvm = try {function () return os.iorunv("brew", {"--prefix", "llvm"}) end}
+            if llvm then
+                local ret = find_tool("llvm-config", {paths = path.join(llvm:trim(), "bin")})
+                if ret then
+                    llvm_config = ret.program
+                end
+            end
+        end
+        local version = try {function() return os.iorunv(llvm_config, {"--version"}) end}
+        if version then
+            version = version:trim()
+        end
+        if package:is_toolchain() then
+            if version then
+                return {version = version}
+            end
+        else
+            local linkdir = try {function() return os.iorunv(llvm_config, {"--libdir"}) end}
+            local includedir = try {function() return os.iorunv(llvm_config, {"--includedir"}) end}
+            if linkdir and includedir then
+                linkdir = linkdir:trim()
+                includedir = includedir:trim()
+                local result = {version = version, linkdirs = linkdir, includedirs = includedir}
+                local components = {}
+                for _, file in ipairs(os.files(path.join(os.scriptdir(), "components", "*.lua"))) do
+                    local name = path.basename(file)
+                    local links = {}
+                    for _, link in ipairs(import("components." .. name).get_links(package)) do
+                        local filename_static = target.filename(link, "static", {plat = package:plat(), arch = package:arch()})
+                        local filename_shared = target.filename(link, "shared", {plat = package:plat(), arch = package:arch()})
+                        if os.isfile(path.join(linkdir, filename_static)) or
+                            os.isfile(path.join(linkdir, filename_shared)) then
+                            table.insert(links, link)
+                        end
+                    end
+                    if #links > 0 then
+                        components[name] = components[name] or {}
+                        components[name].links = links
+                    end
+                end
+                components.__base = {linkdirs = linkdir, includedirs = includedir}
+                result.components = components
+                return result
+            end
+        end
+    end
+end
+

+ 44 - 42
packages/l/llvm/xmake.lua

@@ -4,8 +4,8 @@ package("llvm")
     set_homepage("https://llvm.org/")
     set_description("The LLVM Compiler Infrastructure")
 
-    if is_host("windows") then
-        if os.arch() == "x86" then
+    if is_plat("windows") then
+        if is_arch("x86") then
             set_urls("https://github.com/xmake-mirror/llvm-windows/releases/download/$(version)/clang+llvm-$(version)-win32.zip")
             add_versions("11.0.0", "268043ae0b656cf6272ccb9b8e3f21f51170b74ed8997ddc0b99587983b821ca")
             add_versions("14.0.0", "63afc3c472cb279978c5a7efc25b8783a700aeb416df67886b7057eba52a8742")
@@ -14,20 +14,20 @@ package("llvm")
             add_versions("11.0.0", "db5b3a44f8f784ebc71f716b54eb63c0d8d21aead12449f36291ab00820271c7")
             add_versions("14.0.0", "c1e1ddf11aa73c58073956d9217086550544328ed5e6ec64c1a709badb231711")
         end
-    elseif is_host("macosx") then
-        if os.arch() == "x86_64" then
+    elseif is_plat("macosx") then
+        if is_arch("x86_64") then
             set_urls("https://github.com/llvm/llvm-project/releases/download/llvmorg-$(version)/clang+llvm-$(version)-x86_64-apple-darwin.tar.xz")
             add_versions("11.0.0", "b93886ab0025cbbdbb08b46e5e403a462b0ce034811c929e96ed66c2b07fe63a")
             add_versions("14.0.0", "cf5af0f32d78dcf4413ef6966abbfd5b1445fe80bba57f2ff8a08f77e672b9b3")
-        elseif os.arch() == "arm64" then
+        elseif is_arch("arm64") then
             set_urls("https://github.com/llvm/llvm-project/releases/download/llvmorg-$(version)/clang+llvm-$(version)-arm64-apple-darwin21.0.tar.xz")
             add_versions("15.0.0", "cfd5c3fa07d7fccea0687f5b4498329a6172b7a15bbc45b547d0ac86bd3452a5")
         end
-    elseif is_host("bsd") then
-        if os.arch() == "x86_64" then
+    elseif is_plat("bsd") then
+        if is_arch("x86_64") then
             set_urls("https://github.com/llvm/llvm-project/releases/download/llvmorg-$(version)/clang+llvm-$(version)-amd64-unknown-freebsd13.tar.xz")
             add_versions("14.0.0", "b68d73fd57be385e7f06046a87381f7520c8861f492c294e6301d2843d9a1f57")
-        elseif os.arch() == "i386" then
+        elseif is_arch("i386") then
             set_urls("https://github.com/llvm/llvm-project/releases/download/llvmorg-$(version)/clang+llvm-$(version)-i386-unknown-freebsd13.tar.xz")
             add_versions("14.0.0", "81f49eb466ce9149335ac8918a5f02fa724d562a94464ed13745db0165b4a220")
         end
@@ -37,6 +37,8 @@ package("llvm")
         add_versions("14.0.0", "35ce9edbc8f774fe07c8f4acdf89ec8ac695c8016c165dd86b8d10e7cba07e23")
     end
 
+    add_configs("shared",            {description = "Build shared library.", default = false, type = "boolean", readonly = true})
+
     add_configs("all",               {description = "Enable all projects.", default = false, type = "boolean"})
     add_configs("bolt",              {description = "Enable bolt project.", default = false, type = "boolean"})
     add_configs("clang",             {description = "Enable clang project.", default = true, type = "boolean"})
@@ -56,44 +58,37 @@ package("llvm")
     add_configs("libcxxabi",         {description = "Enable libcxxabi runtime.", default = true, type = "boolean"})
     add_configs("openmp",            {description = "Enable openmp runtime.", default = false, type = "boolean"})
 
-    if is_host("linux") then
-        add_deps("cmake")
-        add_deps("python 3.x", {kind = "binary", host = true})
-        add_deps("zlib", "libffi", {host = true})
-        add_deps("binutils", {host = true}) -- needed for gold and strip
-    end
-
-    on_load("@linux", "@bsd", function (package)
-        if package:config("openmp") then
-            package:add("deps", "libelf", {host = true})
+    on_load(function (package)
+        if package:is_plat("linux") then
+            package:add("deps", "cmake")
+            package:add("deps", "python 3.x", {kind = "binary", host = true})
+            package:add("deps", "zlib", "libffi", {host = true})
+            package:add("deps", "binutils", {host = true}) -- needed for gold and strip
         end
-    end)
-
-    on_fetch(function (package, opt)
-        if opt.system then
-            local llvm_config = "llvm-config"
-            if is_host("macosx") then
-                import("lib.detect.find_tool")
-                local llvm = try {function () return os.iorunv("brew", {"--prefix", "llvm"}) end}
-                if llvm then
-                    local ret = find_tool("llvm-config", {paths = path.join(llvm:trim(), "bin")})
-                    if ret then
-                        llvm_config = ret.program
-                    end
-                end
+        if package:is_plat("linux", "bsd") then
+            if package:config("openmp") then
+                package:add("deps", "libelf", {host = true})
             end
-            local version = try {function() return os.iorunv(llvm_config, {"--version"}) end}
-            if version then
-                return {version = version:trim()}
+        end
+        -- add components
+        if package:is_library() then
+            local components = {"mlir", "clang", "libunwind"}
+            for _, name in ipairs(components) do
+                if package:config(name) or package:config("all") then
+                    package:add("components", name, {deps = "base"})
+                end
             end
+            package:add("components", "base", {default = true})
         end
     end)
 
-    on_install("@macosx", "@windows", "@msys", "@bsd", function (package)
+    on_fetch("fetch")
+
+    on_install("macosx", "windows", "msys", "bsd", function (package)
         os.cp("*", package:installdir())
     end)
 
-    on_install("@linux", function (package)
+    on_install("linux", function (package)
         local projects = {
             "bolt",
             "clang",
@@ -169,11 +164,18 @@ package("llvm")
         import("package.tools.cmake").install(package, configs)
     end)
 
+    on_component("mlir",      "components.mlir")
+    on_component("clang",     "components.clang")
+    on_component("libunwind", "components.libunwind")
+    on_component("base",      "components.base")
+
     on_test(function (package)
-        if not is_host("windows") then
-            os.vrun("llvm-config --version")
-        end
-        if package:config("clang") then
-            os.vrun("clang --version")
+        if package:is_toolchain() and not package:is_cross() then
+            if not package:is_plat("windows") then
+                os.vrun("llvm-config --version")
+            end
+            if package:config("clang") then
+                os.vrun("clang --version")
+            end
         end
     end)