Index: clang/test/Driver/clang-offload-bundler.c =================================================================== --- clang/test/Driver/clang-offload-bundler.c +++ clang/test/Driver/clang-offload-bundler.c @@ -323,6 +323,26 @@ // CKLST2-NOT: openmp-powerpc64le-ibm-linux-gnu // CKLST2-NOT: openmp-x86_64-pc-linux-gnu +// +// Check -fail-on-missing-bundles option +// +// RUN: clang-offload-bundler -type=bc -targets=host-%itanium_abi_triple,hip-amdgcn-amd-amdhsa-gfx900 -inputs=%t.bc,%t.tgt1 -outputs=%t.hip.bundle.bc +// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc -unbundle -fail-on-missing-bundles \ +// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906 \ +// RUN: 2>&1 | FileCheck -check-prefix=MISS1 %s +// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc,%t.tmp2.bc -unbundle -fail-on-missing-bundles \ +// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx900 \ +// RUN: 2>&1 | FileCheck -check-prefix=MISS1 %s +// MISS1: error: Can't find bundles for hip-amdgcn-amd-amdhsa-gfx906 +// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc,%t.tmp2.bc -unbundle -fail-on-missing-bundles \ +// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx803 \ +// RUN: 2>&1 | FileCheck -check-prefix=MISS2 %s +// MISS2: error: Can't find bundles for hip-amdgcn-amd-amdhsa-gfx803 and hip-amdgcn-amd-amdhsa-gfx906 +// RUN: not clang-offload-bundler -type=bc -inputs=%t.hip.bundle.bc -outputs=%t.tmp.bc,%t.tmp2.bc,%t.tmp3.bc -unbundle -fail-on-missing-bundles \ +// RUN: -targets=hip-amdgcn-amd-amdhsa-gfx906,hip-amdgcn-amd-amdhsa-gfx803,hip-amdgcn-amd-amdhsa-gfx1010 \ +// RUN: 2>&1 | FileCheck -check-prefix=MISS3 %s +// MISS3: error: Can't find bundles for hip-amdgcn-amd-amdhsa-gfx1010, hip-amdgcn-amd-amdhsa-gfx803, and hip-amdgcn-amd-amdhsa-gfx906 + // Some code so that we can create a binary out of this file. int A = 0; void test_func(void) { Index: clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp =================================================================== --- clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp +++ clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -99,6 +100,12 @@ "instead of actually executing them - for testing purposes.\n"), cl::init(false), cl::cat(ClangOffloadBundlerCategory)); +static cl::opt + FailOnMissingBundles("fail-on-missing-bundles", + cl::desc("Fail if bundles are missing when" + "unbundling.\n"), + cl::init(false), cl::cat(ClangOffloadBundlerCategory)); + static cl::opt BundleAlignment("bundle-align", cl::desc("Alignment of bundle for binary files"), @@ -969,6 +976,25 @@ FoundHostBundle = true; } + if (FailOnMissingBundles && !Worklist.empty()) { + std::string ErrMsg = "Can't find bundles for"; + std::set Sorted; + for (auto &E : Worklist) + Sorted.insert(E.first()); + unsigned I = 0; + unsigned Last = Worklist.size() - 1; + for (auto &E : Sorted) { + if (I != 0 && Last > 1) + ErrMsg += ","; + ErrMsg += " "; + if (I == Last && I != 0) + ErrMsg += "and "; + ErrMsg += E.str(); + ++I; + } + return createStringError(inconvertibleErrorCode(), ErrMsg); + } + // If no bundles were found, assume the input file is the host bundle and // create empty files for the remaining targets. if (Worklist.size() == TargetNames.size()) {