[flang-commits] [flang] [llvm] [Flang] Add mock flang driver (PR #203481)
Michael Kruse via flang-commits
flang-commits at lists.llvm.org
Wed Jun 17 06:40:24 PDT 2026
================
@@ -0,0 +1,99 @@
+//===-- fakeflang.cpp - Mock Flang Driver ---------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// Mock driver to pass CMake's compiler introspection for
+/// CMake_Fortran_COMPILER. It's purpose is to not having to build the full
+/// flang compiler for the runtimes-configure phase in bootstrapping-runtimes
+/// builds, but only when the Fortran compiler is actually needed (e.g.
+/// flang-rt-mod, libomp-mod).
+///
+/// To detect LLVMFlang, CMake executes
+///
+/// ${CMAKE_Fortran_COMPILER} -v -c -target=... CMakeFortranCompilerId.F
+///
+/// and expects a new file to appear in the working directory. This would
+/// usually be an object file (e.g. ELF), but it doesn't matter for CMake as it
+/// parses it for the preprocessor result of CMakeFortranCompilerId.F which
+/// would appear as string literals in the binary file (CMake cannot execute the
+/// file because it might be cross-compiling). Just passing it through the
+/// preprocessor yields the same result.
+///
+/// The most relevant preprocessor definition is __flang__ which leads to
+/// CMAKE_Fortran_COMPILER_ID="LLVMFlang".
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Version.inc"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/WithColor.h"
+#include <cstdint>
+#include <string>
+
+#define STRINGIFY(X) #X
+#define STRINGIFY_EXPANDED(X) STRINGIFY(X)
+
+static std::string getExecutablePath(const char *argv0) {
+ void *anchor = (void *)(intptr_t)getExecutablePath;
+ return llvm::sys::fs::getMainExecutable(argv0, anchor);
+}
+
+[[noreturn]] static void fail(llvm::Twine Error) {
+ llvm::WithColor::error(llvm::errs(), "fakeflang") << Error << "\n";
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, const char **argv) {
+ llvm::InitLLVM X(argc, argv);
+ std::string SelfExe = getExecutablePath(argv[0]);
+
+ if (llvm::sys::path::stem(SelfExe) == "flang") {
+ llvm::WithColor::remark(llvm::errs())
+ << "This is a mock flang compiler; Use '" STRINGIFY_EXPANDED(
+ CMAKE_MAKE_PROGRAM) " flang' to replace it with the real "
+ "compiler\n";
+ }
+
+ llvm::SmallString<256> ClangExe{llvm::sys::path::parent_path(SelfExe)};
+ llvm::sys::path::append(ClangExe, "clang");
+
+ llvm::ArrayRef<const char *> AllArgs(argv, static_cast<size_t>(argc));
+ bool hasDashO = AllArgs.size() > 1 &&
----------------
Meinersbur wrote:
`cl::Sink` does that. But due to different understanding of command line option parsing, I wouldn't use it for the sake of using it. More examples:
1. Command like order for something like `-Wl,--whole-archive`, `-x c` actually matters, order relative to different options is not preserved by the cl::opt API
2. Many single dash options are actually long-form options, such as `-std`.
https://github.com/llvm/llvm-project/pull/203481
More information about the flang-commits
mailing list