Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 43718f5..d0d8670 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,8 +63,7 @@ if(LLVM_CONFIG)
"--bindir"
"--libdir"
"--includedir"
- "--prefix"
- "--src-root")
+ "--prefix")
execute_process(COMMAND ${CONFIG_COMMAND}
RESULT_VARIABLE HAD_ERROR
OUTPUT_VARIABLE CONFIG_OUTPUT)
diff --git a/src/xmagics/executable.cpp b/src/xmagics/executable.cpp
index 391c8c9..aba5e03 100644
--- a/src/xmagics/executable.cpp
+++ b/src/xmagics/executable.cpp
@@ -12,6 +12,7 @@
#include <iterator>
#include <fstream>
#include <memory>
+#include <optional>
#include <string>
#include <vector>

@@ -25,7 +26,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/Basic/DebugInfoOptions.h"
+#include "llvm/Frontend/Debug/Options.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/BackendUtil.h"
@@ -115,7 +116,7 @@ namespace xcpp
// Filter out functions added by Cling.
if (auto Identifier = D->getIdentifier())
{
- if (Identifier->getName().startswith("__cling"))
+ if (Identifier->getName().starts_with("__cling"))
{
return true;
}
@@ -153,12 +154,13 @@ namespace xcpp
if (EnableDebugInfo)
{
CodeGenOpts.setDebugInfo(
- clang::codegenoptions::DebugInfoKind::FullDebugInfo);
+ llvm::codegenoptions::DebugInfoKind::FullDebugInfo);
}

std::unique_ptr<clang::CodeGenerator> CG(clang::CreateLLVMCodeGen(
- CI->getDiagnostics(), "object", HeaderSearchOpts,
- CI->getPreprocessorOpts(), CodeGenOpts, *Context));
+ CI->getDiagnostics(), "object",
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>(&CI->getVirtualFileSystem()),
+ HeaderSearchOpts, CI->getPreprocessorOpts(), CodeGenOpts, *Context));
CG->Initialize(AST);

FindTopLevelDecls Visitor(CG.get());
@@ -186,7 +188,9 @@ namespace xcpp
EmitBackendOutput(CI->getDiagnostics(), HeaderSearchOpts,
CodeGenOpts, CI->getTargetOpts(),
CI->getLangOpts(), DataLayout, CG->GetModule(),
- clang::Backend_EmitObj, std::move(OS));
+ clang::Backend_EmitObj,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>(&CI->getVirtualFileSystem()),
+ std::move(OS));
return true;
}

@@ -222,10 +226,10 @@ namespace xcpp

llvm::StringRef OutputFileStr(OutputFile);
llvm::StringRef ErrorFileStr(ErrorFile);
- llvm::SmallVector<llvm::Optional<llvm::StringRef>, 16> Redirects = {llvm::NoneType::None, OutputFileStr, ErrorFileStr};
+ llvm::SmallVector<std::optional<llvm::StringRef>, 16> Redirects = {std::nullopt, OutputFileStr, ErrorFileStr};

// Finally run the linker.
- int ret = llvm::sys::ExecuteAndWait(Compiler, Args, llvm::NoneType::None,
+ int ret = llvm::sys::ExecuteAndWait(Compiler, Args, std::nullopt,
Redirects);

// Read back output and error streams.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
clangStdenv,
cmake,
fetchFromGitHub,
llvmPackages_13,
llvmPackages_18,
# Libraries
argparse,
cling,
Expand Down Expand Up @@ -65,6 +65,7 @@ clangStdenv.mkDerivation rec {
patches = [
./0001-Fix-bug-in-extract_filename.patch
./0002-Don-t-pass-extra-includes-configure-this-with-flags.patch
./0003-Remove-unsupported-src-root-flag.patch
];

nativeBuildInputs = [ cmake ];
Expand All @@ -73,7 +74,7 @@ clangStdenv.mkDerivation rec {
cling.unwrapped
cppzmq
libuuid
llvmPackages_13.llvm
llvmPackages_18.llvm
ncurses
openssl
pugixml
Expand Down
54 changes: 54 additions & 0 deletions pkgs/by-name/cl/cling/fix-new-parser.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
From cd4d1d8c4963620a6a84834948845df81fbbd70b Mon Sep 17 00:00:00 2001
From: Jonas Hahnfeld <jonas.hahnfeld@cern.ch>
Date: Tue, 17 Dec 2024 14:54:18 +0100
Subject: [PATCH] Use single Parser for LookupHelper

It is the only construction of a temporary parser, and it seems not
necessary (anymore).
---
include/cling/Interpreter/LookupHelper.h | 2 +-
lib/Interpreter/Interpreter.cpp | 11 ++++-------
2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/include/cling/Interpreter/LookupHelper.h b/include/cling/Interpreter/LookupHelper.h
index 6e6e281470..cd79b2a65c 100644
--- a/include/cling/Interpreter/LookupHelper.h
+++ b/include/cling/Interpreter/LookupHelper.h
@@ -56,7 +56,7 @@ namespace cling {
WithDiagnostics
};
private:
- std::unique_ptr<clang::Parser> m_Parser;
+ clang::Parser* m_Parser;
Interpreter* m_Interpreter; // we do not own.
std::array<const clang::Type*, kNumCachedStrings> m_StringTy = {{}};
/// A map containing the hash of the lookup buffer. This allows us to avoid
diff --git a/lib/Interpreter/Interpreter.cpp b/lib/Interpreter/Interpreter.cpp
index 13c8409cc5..f04695439b 100644
--- a/lib/Interpreter/Interpreter.cpp
+++ b/lib/Interpreter/Interpreter.cpp
@@ -265,13 +265,6 @@ namespace cling {
}

Sema& SemaRef = getSema();
- Preprocessor& PP = SemaRef.getPreprocessor();
-
- m_LookupHelper.reset(new LookupHelper(new Parser(PP, SemaRef,
- /*SkipFunctionBodies*/false,
- /*isTemp*/true), this));
- if (!m_LookupHelper)
- return;

if (!isInSyntaxOnlyMode() && !m_Opts.CompilerOpts.CUDADevice) {
m_Executor.reset(new IncrementalExecutor(SemaRef.Diags, *getCI(),
@@ -317,6 +310,10 @@ namespace cling {
return;
}

+ m_LookupHelper.reset(new LookupHelper(m_IncrParser->getParser(), this));
+ if (!m_LookupHelper)
+ return;
+
// When not using C++ modules, we now have a PCH and we can safely setup
// our callbacks without fearing that they get overwritten by clang code.
// The modules setup is handled above.
13 changes: 0 additions & 13 deletions pkgs/by-name/cl/cling/no-clang-cpp.patch

This file was deleted.

88 changes: 40 additions & 48 deletions pkgs/by-name/cl/cling/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
git,
lib,
libffi,
llvmPackages_13,
llvmPackages_18,
makeWrapper,
ncurses,
python3,
zlib,

# *NOT* from LLVM 13!
# *NOT* from LLVM 18!
# The compiler used to compile Cling may affect the runtime include and lib
# directories it expects to be run with. Cling builds against (a fork of) Clang,
# so we prefer to use Clang as the compiler as well for consistency.
Expand All @@ -34,41 +34,38 @@
let
stdenv = clangStdenv;

# The patched clang lives in the LLVM megarepo
clangSrc = fetchFromGitHub {
version = "1.2";

clingSrc = fetchFromGitHub {
owner = "root-project";
repo = "llvm-project";
# cling-llvm13 branch
rev = "3610201fbe0352a63efb5cb45f4ea4987702c735";
sha256 = "sha256-Cb7BvV7yobG+mkaYe7zD2KcnPvm8/vmVATNWssklXyk=";
sparseCheckout = [ "clang" ];
repo = "cling";
rev = "v${version}";
sha256 = "sha256-ay9FXANJmB/+AdnCR4WOKHuPm6P88wLqoOgiKJwJ8JM=";
};

llvm = llvmPackages_13.llvm.override { enableSharedLibraries = false; };

unwrapped = stdenv.mkDerivation rec {
unwrapped = stdenv.mkDerivation {
pname = "cling-unwrapped";
version = "1.0";

src = "${clangSrc}/clang";
inherit version;

clingSrc = fetchFromGitHub {
src = fetchFromGitHub {
owner = "root-project";
repo = "cling";
rev = "v${version}";
sha256 = "sha256-Ye8EINzt+dyNvUIRydACXzb/xEPLm0YSkz08Xxw3xp4=";
repo = "llvm-project";
rev = "cling-llvm18-20250721-01";
sha256 = "sha256-JGteapyujU5w81DsfPQfTq76cYHgk5PbAFbdYfYIDo4=";
};

prePatch = ''
echo "add_llvm_external_project(cling)" >> tools/CMakeLists.txt
preConfigure = ''
cp -r ${clingSrc} cling-source

cp -r $clingSrc tools/cling
chmod -R a+w tools/cling
'';
# Patch a bug in version 1.2 by backporting a fix. See
# https://github.com/root-project/cling/issues/556
chmod -R u+w cling-source
pushd cling-source
patch -p1 < ${./fix-new-parser.patch}
popd

patches = [
./no-clang-cpp.patch
];
cd llvm
'';

nativeBuildInputs = [
python3
Expand All @@ -84,22 +81,15 @@ let
strictDeps = true;

cmakeFlags = [
"-DLLVM_BINARY_DIR=${llvm.out}"
"-DLLVM_CONFIG=${llvm.dev}/bin/llvm-config"
"-DLLVM_LIBRARY_DIR=${llvm.lib}/lib"
"-DLLVM_MAIN_INCLUDE_DIR=${llvm.dev}/include"
"-DLLVM_TABLEGEN_EXE=${llvm.out}/bin/llvm-tblgen"
"-DLLVM_TOOLS_BINARY_DIR=${llvm.out}/bin"
"-DLLVM_BUILD_TOOLS=Off"
"-DLLVM_TOOL_CLING_BUILD=ON"

"-DLLVM_EXTERNAL_PROJECTS=cling"
"-DLLVM_EXTERNAL_CLING_SOURCE_DIR=../../cling-source"
"-DLLVM_ENABLE_PROJECTS=clang"
"-DLLVM_TARGETS_TO_BUILD=host;NVPTX"
"-DLLVM_INCLUDE_TESTS=OFF"
"-DLLVM_ENABLE_RTTI=ON"

# Setting -DCLING_INCLUDE_TESTS=ON causes the cling/tools targets to be built;
# see cling/tools/CMakeLists.txt
"-DCLING_INCLUDE_TESTS=ON"
"-DCLANG-TOOLS=OFF"
]
++ lib.optionals (!debug) [
"-DCMAKE_BUILD_TYPE=Release"
]
++ lib.optionals debug [
"-DCMAKE_BUILD_TYPE=Debug"
Expand All @@ -111,11 +101,13 @@ let

CPPFLAGS = if useLLVMLibcxx then [ "-stdlib=libc++" ] else [ ];

postInstall = lib.optionalString (!stdenv.hostPlatform.isDarwin) ''
postInstall = ''
mkdir -p $out/share/Jupyter
cp -r /build/clang/tools/cling/tools/Jupyter/kernel $out/share/Jupyter
cp -r ../../cling-source/tools/Jupyter/kernel $out/share/Jupyter
'';

buildTargets = [ "cling" ];

dontStrip = debug;

meta = with lib; {
Expand Down Expand Up @@ -147,18 +139,18 @@ let
"-nostdinc++"

"-resource-dir"
"${llvm.lib}/lib"
"${llvmPackages_18.llvm.lib}/lib"

"-isystem"
"${lib.getLib unwrapped}/lib/clang/${llvmPackages_13.clang.version}/include"
"${lib.getLib unwrapped}/lib/clang/18/include"
]
++ lib.optionals useLLVMLibcxx [
"-I"
"${lib.getDev llvmPackages_13.libcxx}/include/c++/v1"
"${lib.getDev llvmPackages_18.libcxx}/include/c++/v1"
"-L"
"${llvmPackages_13.libcxx}/lib"
"${llvmPackages_18.libcxx}/lib"
"-l"
"${llvmPackages_13.libcxx}/lib/libc++${stdenv.hostPlatform.extensions.sharedLibrary}"
"${llvmPackages_18.libcxx}/lib/libc++${stdenv.hostPlatform.extensions.sharedLibrary}"
Comment on lines 150 to 153
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should probably use stdenv.cc.libcxx, as the libc++ libraries are backwards‐compatible with older headers but mixing the library versions is a bad idea. (Not a blocker, as it’s not a new problem.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean llvmPackages_18.libcxx -> stdenv.cc.libcxx? That doesn't seem like a good idea considering these are library flags. And also that we deliberately use clangStdenv above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clangStdenv doesn’t imply the use of libstdc++ vs. libc++, only the C compiler; it keeps the default C++ library for the platform. (libcxxStdenv explicitly picks the combination of Clang and libc++.)

The C++ standard library is ABI‐sensitive, so mixing different versions of libc++, or libstdc++ with libc++, can cause compatibility issues. However, libc++’s headers only work with a specific range of Clang versions, but can be used to target later versions of the library. So it is correct to use a specific include directory here, but you generally want to ensure the use of the same version to actually link with.

That’s why it probably doesn’t make sense to have a separate useLLVMLibcxx here, as opposed to conditioning on the platform (and hence why I dropped it in my PR). So, in that case, stdenv.cc.libcxx would be non‐null exactly when the platform uses libc++, and you’d want to link with that version while using the headers from Cling’s version of LLVM.

Anyway, this is all stuff you don’t have to think about if you reuse our existing wrapper logic, ideally :) And in this case hopefully the things Cling builds don’t link with much, so the scope for problems is limited. But generally linking against a specific C++ standard library isn’t too reliable (and indeed problems with mixing them in obscure cases are what is driving us to switch to linking against the system‐provided library from the SDK on Darwin).

]
++ lib.optionals (!useLLVMLibcxx) [
"-I"
Expand Down
Loading