### Install Firefox on Windows x86 Source: https://cppinterop.readthedocs.io/en/latest/Emscripten-build-instructions.html Download the latest Firefox installer for Windows x64 and execute it to install Firefox. The installer is saved as firefox-setup.exe. ```powershell Invoke-WebRequest -Uri "https://download.mozilla.org/?product=firefox-latest-ssl&os=win64&lang=en-US" -OutFile "firefox-setup.exe" -Verbose & "C:\Program Files\7-Zip\7z.exe" x "firefox-setup.exe" ``` -------------------------------- ### Install Chrome and Firefox on Ubuntu x86 Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Installs Google Chrome and Firefox on Ubuntu x86 and adds their executables to the PATH for testing. ```bash wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb dpkg-deb -x google-chrome-stable_current_amd64.deb $PWD/chrome cd ./chrome/opt/google/chrome/ export PATH="$PWD:$PATH" cd - wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-x86_64/en-GB/firefox-138.0.1.tar.xz tar -xJf firefox-138.0.1.tar.xz cd ./firefox export PATH="$PWD:$PATH" cd - ``` -------------------------------- ### Install Google Chrome on Ubuntu x86 Source: https://cppinterop.readthedocs.io/en/latest/Emscripten-build-instructions.html Download and install Google Chrome stable version for Ubuntu x86. This sets up the browser in a local directory and exports its path. ```bash wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb dpkg-deb -x google-chrome-stable_current_amd64.deb $PWD/chrome cd ./chrome/opt/google/chrome/ export PATH="$PWD:$PATH" cd - ``` -------------------------------- ### Install Firefox on Ubuntu Arm Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Installs Firefox on Ubuntu Arm and adds its executable to the PATH for testing. ```bash wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-aarch64/en-GB/firefox-138.0.1.tar.xz tar -xJf firefox-138.0.1.tar.xz cd ./firefox export PATH="$PWD:$PATH" cd - ``` -------------------------------- ### Install cppyy Source: https://cppinterop.readthedocs.io/en/latest/InstallationAndUsage.html Clones the cppyy repository and installs it using pip. It is recommended to install without dependencies and build isolation. ```bash git clone --depth=1 https://github.com/compiler-research/cppyy.git cd cppyy python -m pip install --upgrade . --no-deps --no-build-isolation cd .. ``` -------------------------------- ### Run cppyy Source: https://cppinterop.readthedocs.io/en/latest/_sources/DevelopersDocumentation.rst.txt Activate the environment and verify cppyy installation. ```bash source .venv/bin/activate python -c "import cppyy" ``` -------------------------------- ### Install Chrome and Firefox on Windows x86 Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Downloads and extracts Google Chrome and Firefox installers for Windows x86. ```powershell Invoke-WebRequest -Uri "https://commondatastorage.googleapis.com/chromium-browser-snapshots/Win/1411573/chrome-win.zip" -OutFile "$PWD\chrome-win.zip" -Verbose Expand-Archive -Path "$PWD\chrome-win.zip" -DestinationPath "$PWD" -Force -Verbose Invoke-WebRequest -Uri "https://download.mozilla.org/?product=firefox-latest-ssl&os=win64&lang=en-US" -OutFile "firefox-setup.exe" -Verbose & "C:\Program Files\7-Zip\7z.exe" x "firefox-setup.exe" ``` -------------------------------- ### Install CppInterOp Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Install CppInterOp after all tests have passed. This command utilizes nproc to determine the number of available processing units for parallel installation. ```bash emmake make -j $(nproc --all) install ``` -------------------------------- ### Install and Activate emsdk Source: https://cppinterop.readthedocs.io/en/latest/Emscripten-build-instructions.html Install and activate version 4.0.9 of the emsdk toolchain. ```bash git clone https://github.com/emscripten-core/emsdk.git ./emsdk/emsdk install 4.0.9 ``` ```bash ./emsdk/emsdk activate 4.0.9 source ./emsdk/emsdk_env.sh export SYSROOT_PATH=$PWD/emsdk/upstream/emscripten/cache/sysroot ``` ```powershell .\emsdk\emsdk activate 4.0.9 .\emsdk\emsdk_env.ps1 $env:PWD_DIR= $PWD.Path $env:SYSROOT_PATH="$env:EMSDK/upstream/emscripten/cache/sysroot" ``` -------------------------------- ### Initialize Build Directory Source: https://cppinterop.readthedocs.io/en/latest/Emscripten-build-instructions.html Create and enter the directory for the CppInterOp WebAssembly build. ```bash mkdir CppInterOp-wasm cd ./CppInterOp-wasm ``` -------------------------------- ### Start Trace Region Source: https://cppinterop.readthedocs.io/en/latest/build/html/Tracing_8cpp_source.html Begins a traced region. Returns the path where StopTracing will write. Requires setup for logging and file system operations. ```cpp std::string TraceInfo::StartRegion() { m_RegionStart = m_Log.size(); m_InRegion = true; llvm::SmallString<128> TmpDir; llvm::sys::path::system_temp_directory(/*ErasedOnReboot=*/true, TmpDir); llvm::SmallString<128> Path; llvm::sys::path::append(Path, TmpDir, "cppinterop-reproducer-%%%%%%.cpp"); int FD; std::error_code EC = llvm::sys::fs::createUniqueFile(Path, FD, Path); if (EC) return ""; llvm::sys::Process::SafelyCloseFileDescriptor(FD); m_RegionPath = std::string(Path); return m_RegionPath; } ``` -------------------------------- ### Build Cling and LLVM Source: https://cppinterop.readthedocs.io/en/latest/_sources/DevelopersDocumentation.rst.txt Build instructions for Linux/MacOS and Windows environments. ```bash git clone --depth=1 --branch v1.3 https://github.com/root-project/cling.git git clone --depth=1 -b cling-llvm20-20260119-01 https://github.com/root-project/llvm-project.git mkdir llvm-project/build cd llvm-project/build cmake -DLLVM_ENABLE_PROJECTS=clang \ -DLLVM_EXTERNAL_PROJECTS=cling \ -DLLVM_EXTERNAL_CLING_SOURCE_DIR=../../cling \ -DLLVM_TARGETS_TO_BUILD="host;NVPTX" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DCLANG_ENABLE_STATIC_ANALYZER=OFF \ -DCLANG_ENABLE_ARCMT=OFF \ -DCLANG_ENABLE_FORMAT=OFF \ -DCLANG_ENABLE_BOOTSTRAP=OFF \ ../llvm cmake --build . --target clang --parallel $(nproc --all) cmake --build . --target cling --parallel $(nproc --all) ``` ```powershell git clone --depth=1 --branch v1.3 https://github.com/root-project/cling.git git clone --depth=1 -b cling-llvm20-20260119-01 https://github.com/root-project/llvm-project.git $env:ncpus = $([Environment]::ProcessorCount) $env:PWD_DIR= $PWD.Path $env:CLING_DIR="$env:PWD_DIR\cling" mkdir llvm-project\build cd llvm-project\build cmake -DLLVM_ENABLE_PROJECTS=clang ` -DLLVM_EXTERNAL_PROJECTS=cling ` -DLLVM_EXTERNAL_CLING_SOURCE_DIR="$env:CLING_DIR" ` -DLLVM_TARGETS_TO_BUILD="host;NVPTX" ` -DCMAKE_BUILD_TYPE=Release ` -DLLVM_ENABLE_ASSERTIONS=ON ` -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` -DCLANG_ENABLE_ARCMT=OFF ` -DCLANG_ENABLE_FORMAT=OFF ` -DCLANG_ENABLE_BOOTSTRAP=OFF ` ../llvm cmake --build . --target clang --parallel $env:ncpus cmake --build . --target cling --parallel $env:ncpus ``` -------------------------------- ### Example: Creating a Python Type for C++ Class 'A' Source: https://cppinterop.readthedocs.io/en/latest/_sources/tutorials.rst.txt Demonstrates creating a Python type 'CppA' that wraps the C++ class 'A'. It uses the CppInterOpLayerWrapper to get the scope of 'A' and defines a custom allocation method. ```python if __name__ == '__main__': # create a couple of types to play with CppA = type('A', (), { 'handle' : gIL.get_scope('A'), '__new__' : cpp_allocate }) ``` -------------------------------- ### Creating the Interpreter Instance Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Main function to instantiate and configure the interpreter with provided arguments and GPU-specific settings. ```cpp TInterp_t CreateInterpreter(const std::vector& Args /*={}*/, const std::vector& GpuArgs /*={}*/) { INTEROP_TRACE(Args, GpuArgs); std::string MainExecutableName = sys::fs::getMainExecutable(nullptr, nullptr); // In some systems, CppInterOp cannot manually detect the correct resource. // Then the -resource-dir passed by the user is assumed to be the correct // location. Prioritising it over detecting it within CppInterOp. Extracting // the resource-dir from the arguments is required because we set the // necessary library search location explicitly below. Because by default, // linker flags are ignored in repl (issue #748) std::string ResourceDir = ExtractArgument(Args, "-resource-dir"); if (ResourceDir.empty()) ResourceDir = MakeResourcesPath(); llvm::Triple T(llvm::sys::getProcessTriple()); if ((!sys::fs::is_directory(ResourceDir)) && (T.isOSDarwin() || T.isOSLinux())) ResourceDir = DetectResourceDir(); std::vector ClingArgv = {"-resource-dir", ResourceDir.c_str(), "-std=c++14"}; ClingArgv.insert(ClingArgv.begin(), MainExecutableName.c_str()); #ifdef _WIN32 // FIXME : Workaround Sema::PushDeclContext assert on windows ClingArgv.push_back("-fno-delayed-template-parsing"); #endif ClingArgv.insert(ClingArgv.end(), Args.begin(), Args.end()); // To keep the Interpreter creation interface between cling and clang-repl // to some extent compatible we should put Args and GpuArgs together. On the // receiving end we should check for -xcuda to know. if (!GpuArgs.empty()) { llvm::StringRef Arg0 = GpuArgs[0]; Arg0 = Arg0.trim().ltrim('-'); if (Arg0 != "cuda") { llvm::errs() << "[CreateInterpreter]: Make sure --cuda is passed as the" << " first argument of the GpuArgs\n"; return INTEROP_RETURN(nullptr); } } ClingArgv.insert(ClingArgv.end(), GpuArgs.begin(), GpuArgs.end()); // Process externally passed arguments if present. std::vector ExtraArgs; auto EnvOpt = llvm::sys::Process::GetEnv("CPPINTEROP_EXTRA_INTERPRETER_ARGS"); if (EnvOpt) { StringRef Env(*EnvOpt); while (!Env.empty()) { StringRef Arg; std::tie(Arg, Env) = Env.split(' '); ExtraArgs.push_back(Arg.str()); } } std::transform(ExtraArgs.begin(), ExtraArgs.end(), std::back_inserter(ClingArgv), [&](const std::string& str) { return str.c_str(); }); // Force global process initialization. (void)GetInterpreters(); #ifdef CPPINTEROP_USE_CLING auto I = new compat::Interpreter(ClingArgv.size(), &ClingArgv[0]); #else auto Interp = compat::Interpreter::create(static_cast(ClingArgv.size()), ClingArgv.data(), nullptr, {}, nullptr, true); if (!Interp) return INTEROP_RETURN(nullptr); auto* I = Interp.release(); #endif // Honor -mllvm. // // FIXME: Remove this, one day. // This should happen AFTER plugins have been loaded! const CompilerInstance* Clang = I->getCI(); if (!Clang->getFrontendOpts().LLVMArgs.empty()) { unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size(); auto Args = std::make_unique(NumArgs + 2); Args[0] = "clang (LLVM option parsing)"; for (unsigned i = 0; i != NumArgs; ++i) Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str(); Args[NumArgs + 1] = nullptr; llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get()); } if (!T.isWasm()) AddLibrarySearchPaths(ResourceDir, I); if (GetLanguage(I) != InterpreterLanguage::C) { I->declare(R"( namespace __internal_CppInterOp { template struct function; template struct function { typedef Res result_type; }; } // namespace __internal_CppInterOp )"); } RegisterInterpreter(I, /*Owned=*/true); // Define runtime symbols in the JIT dylib for clang-repl #if !defined(CPPINTEROP_USE_CLING) && !defined(EMSCRIPTEN) DefineAbsoluteSymbol(*I, "__ci_newtag", reinterpret_cast(&__ci_newtag)); // llvm >= 21 has this defined as a C symbol that does not require mangling #if CLANG_VERSION_MAJOR >= 21 DefineAbsoluteSymbol( *I, "__clang_Interpreter_SetValueWithAlloc", ``` -------------------------------- ### Create a Debug-Ready Test Program Source: https://cppinterop.readthedocs.io/en/latest/_sources/DebuggingCppInterOp.rst.txt This C++ example demonstrates initializing the interpreter with debug flags, declaring dynamic code, and executing mixed compiled and interpreted code paths. It's suitable for debugging common CppInterOp usage patterns. ```cpp #include #include void run_code(std::string code) { Cpp::Declare(code.c_str()); } int main(int argc, char *argv[]) { Cpp::CreateInterpreter({"-gdwarf-4", "-O0"}); std::vector Decls; std::string code = R"( #include void f1() { std::cout << "in f1 function" << std::endl; } std::cout << "In codeblock 1" << std::endl; int a = 100; int b = 1000; )"; run_code(code); code = R"( f1(); )"; run_code(code); return 0; } ``` -------------------------------- ### Navigate to Top Level Directory Source: https://cppinterop.readthedocs.io/en/latest/_sources/DevelopersDocumentation.rst.txt Return to the top-level directory from the build folder. ```bash cd ../.. ``` ```powershell cd ..\.. ``` -------------------------------- ### Initialize CppInterOp Build Directory Source: https://cppinterop.readthedocs.io/en/latest/_sources/DevelopersDocumentation.rst.txt Create the build directory for CppInterOp. ```bash mkdir CppInterOp/build/ ``` -------------------------------- ### Navigate to Build Directory Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Change your current directory to the newly created CppInterOp-wasm folder. ```bash cd ./CppInterOp-wasm ``` -------------------------------- ### Install Firefox and Chrome on macOS Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Installs the latest versions of Firefox and Chrome on macOS and adds their executables to the PATH for testing. ```bash wget "https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US" -O Firefox-latest.dmg hdiutil attach Firefox-latest.dmg cp -r /Volumes/Firefox/Firefox.app $PWD hdiutil detach /Volumes/Firefox cd ./Firefox.app/Contents/MacOS/ export PATH="$PWD:$PATH" cd - wget https://dl.google.com/chrome/mac/stable/accept_tos%3Dhttps%253A%252F%252Fwww.google.com%252Fintl%252Fen_ph%252Fchrome%252Fterms%252F%26_and_accept_tos%3Dhttps%253A%252F%252Fpolicies.google.com%252Fterms/googlechrome.pkg pkgutil --expand-full googlechrome.pkg google-chrome cd ./google-chrome/GoogleChrome.pkg/Payload/Google\ Chrome.app/Contents/MacOS/ export PATH="$PWD:$PATH" cd - ``` -------------------------------- ### Create Build Directory (Linux/macOS) Source: https://cppinterop.readthedocs.io/en/latest/InstallationAndUsage.html Creates and navigates into the build directory for CppInterOp on Linux and macOS. ```bash mkdir CppInterOp/build/ cd CppInterOp/build/ ``` -------------------------------- ### Get Type as String Helper Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Helper function to get the string representation of a QualType. This function is intended for internal use. ```cpp void get_type_as_string(QualType QT, std::string& type_name, ASTContext& C, PrintingPolicy Policy) { ``` -------------------------------- ### StartTracing Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppInterOp_1_1Tracing.html Begins recording a traced region and returns the path where the reproducer will be written. ```APIDOC ## std::string StartTracing() ### Description Begin recording a traced region. If tracing is not yet active, activates it. Returns the path where StopTracing() will write the reproducer. ``` -------------------------------- ### Install emsdk Toolchain Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Clone the emsdk repository and install version 4.0.9 of the Emscripten SDK. This toolchain is required for building WebAssembly. ```bash git clone https://github.com/emscripten-core/emsdk.git ./emsdk/emsdk install 4.0.9 ``` -------------------------------- ### Detect CUDA Install Path Source: https://cppinterop.readthedocs.io/en/latest/build/html/Compatibility_8h_source.html Detects the CUDA installation path using clang::Driver. Takes a vector of arguments and a string reference for the path. ```cpp bool detectCudaInstallPath(const std::vector< const char * > &args, std::string &CudaPath) ``` -------------------------------- ### Build CppInterOp with Cling Source: https://cppinterop.readthedocs.io/en/latest/_sources/DevelopersDocumentation.rst.txt Configure and build CppInterOp using Cling on different platforms. ```bash cmake -DBUILD_SHARED_LIBS=ON -DCPPINTEROP_USE_CLING=ON -DCPPINTEROP_USE_REPL=Off -DCling_DIR=$LLVM_DIR/build/tools/cling -DLLVM_DIR=$LLVM_DIR/build/lib/cmake/llvm -DClang_DIR=$LLVM_DIR/build/lib/cmake/clang -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR .. cmake --build . --target install --parallel $(nproc --all) ``` ```powershell cmake -DCPPINTEROP_USE_CLING=ON -DCPPINTEROP_USE_REPL=Off -DCling_DIR=$env:LLVM_DIR\build\tools\cling -DLLVM_DIR=$env:LLVM_DIR\build\lib\cmake\llvm -DClang_DIR=$env:LLVM_DIR\build\lib\cmake\clang -DCMAKE_INSTALL_PREFIX=$env:CPPINTEROP_DIR .. cmake --build . --target install --parallel $env:ncpus ``` -------------------------------- ### Build Cling and LLVM-Project on Linux/macOS Source: https://cppinterop.readthedocs.io/en/latest/DevelopersDocumentation.html Use these commands to clone the necessary repositories and build Cling and LLVM-project on Linux and macOS systems. Ensure you have git and cmake installed. ```bash git clone --depth=1 --branch v1.3 https://github.com/root-project/cling.git git clone --depth=1 -b cling-llvm20-20260119-01 https://github.com/root-project/llvm-project.git mkdir llvm-project/build cd llvm-project/build cake -DLLVM_ENABLE_PROJECTS=clang \ -DLLVM_EXTERNAL_PROJECTS=cling \ -DLLVM_EXTERNAL_CLING_SOURCE_DIR=../../cling \ -DLLVM_TARGETS_TO_BUILD="host;NVPTX" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DCLANG_ENABLE_STATIC_ANALYZER=OFF \ -DCLANG_ENABLE_ARCMT=OFF \ -DCLANG_ENABLE_FORMAT=OFF \ -DCLANG_ENABLE_BOOTSTRAP=OFF \ ../llvm cake --build . --target clang --parallel $(nproc --all) cake --build . --target cling --parallel $(nproc --all) ``` -------------------------------- ### Build Cling and LLVM Project on Windows Source: https://cppinterop.readthedocs.io/en/latest/_sources/InstallationAndUsage.rst.txt Clone the Cling and LLVM project repositories and configure the build using CMake on Windows. This process sets up the necessary components for building CppInterOp. ```powershell git clone --depth=1 --branch v1.3 https://github.com/root-project/cling.git git clone --depth=1 -b cling-llvm20-20260119-01 https://github.com/root-project/llvm-project.git $env:ncpus = ([Environment]::ProcessorCount) $env:PWD_DIR= $PWD.Path $env:CLING_DIR="$env:PWD_DIR\cling" mkdir llvm-project\build cd llvm-project\build cmake -DLLVM_ENABLE_PROJECTS=clang \ -DLLVM_EXTERNAL_PROJECTS=cling \ -DLLVM_EXTERNAL_CLING_SOURCE_DIR="$env:CLING_DIR" \ -DLLVM_TARGETS_TO_BUILD="host;NVPTX" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DCLANG_ENABLE_STATIC_ANALYZER=OFF \ -DCLANG_ENABLE_ARCMT=OFF \ -DCLANG_ENABLE_FORMAT=OFF \ -DCLANG_ENABLE_BOOTSTRAP=OFF \ ../llvm cmake --build . --target clang --parallel $env:ncpus cmake --build . --target cling --parallel $env:ncpus ``` -------------------------------- ### Get Type from Scope for C++ Interop Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Retrieves a type from the current scope using its declaration. It first attempts to get the type internally and returns null if the scope or type is invalid. ```cpp TCppType_t GetTypeFromScope(TCppScope_t klass) { INTEROP_TRACE(klass); if (!klass) return INTEROP_RETURN(nullptr); if (auto QT = GetTypeInternal((Decl*)klass)) return INTEROP_RETURN(QT->getAsOpaquePtr()); return INTEROP_RETURN(nullptr); } ``` -------------------------------- ### Build Clang-REPL on Windows Source: https://cppinterop.readthedocs.io/en/latest/DevelopersDocumentation.html CMake configuration and build commands for Windows environments. ```powershell $env:ncpus = $([Environment]::ProcessorCount) mkdir build cd build cmake -DLLVM_ENABLE_PROJECTS=clang ` -DLLVM_TARGETS_TO_BUILD="host;NVPTX" ` -DCMAKE_BUILD_TYPE=Release ` -DLLVM_ENABLE_ASSERTIONS=ON ` -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` -DCLANG_ENABLE_ARCMT=OFF ` -DCLANG_ENABLE_FORMAT=OFF ` -DCLANG_ENABLE_BOOTSTRAP=OFF ` ..\llvm cmake --build . --target clang clang-repl --parallel $env:ncpus ``` -------------------------------- ### Get Symbol Location on Windows Source: https://cppinterop.readthedocs.io/en/latest/build/html/DynamicLibraryManagerSymbol_8cpp_source.html Retrieves the location (module file name) of a given function pointer on Windows systems. It uses VirtualQuery to find the module and then GetModuleFileNameA to get the path. ```cpp #elif defined(_WIN32) MEMORY_BASIC_INFORMATION mbi; if (!VirtualQuery(func, &mbi, sizeof(mbi))) return {}; HMODULE hMod = (HMODULE)mbi.AllocationBase; char moduleName[MAX_PATH]; if (!GetModuleFileNameA(hMod, moduleName, sizeof(moduleName))) return {}; return cached_realpath(moduleName); ``` -------------------------------- ### Create and Activate Virtual Environment for CPyCppyy Source: https://cppinterop.readthedocs.io/en/latest/InstallationAndUsage.html Creates a Python virtual environment named .venv, activates it, clones the CPyCppyy repository, and prepares for building. ```bash python3 -m venv .venv source .venv/bin/activate git clone --depth=1 https://github.com/compiler-research/CPyCppyy.git mkdir CPyCppyy/build cd CPyCppyy/build cmake .. cmake --build . ``` -------------------------------- ### Get Destructor for C++ Record Source: https://cppinterop.readthedocs.io/en/latest/build/html/CXCppInterOp_8cpp_source.html Retrieves the destructor for a C++ record declaration. Ensures implicit members are declared before attempting to get the destructor. Returns a null scope if the input is not a C++ record or if the destructor cannot be found. ```cpp CXScope clang_getDestructor(CXScope S) { auto* D = getDecl(S); if (auto* CXXRD = llvm::dyn_cast_or_null(D)) { getInterpreter(S)->getSema().ForceDeclarationOfImplicitMembers(CXXRD); return clang::cxscope::MakeCXScope(CXXRD->getDestructor(), getNewTU(S)); } return clang::cxscope::MakeCXScope(nullptr, getNewTU(S)); } ``` -------------------------------- ### GetDimensions() Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppImpl.html Gets the size/dimensions of a multi-dimension array. ```APIDOC ## GetDimensions() ### Description Gets the size/dimensions of a multi-dimension array. ### Method Not specified (likely a member function of CppImpl) ### Endpoint N/A (This is a C++ function, not a REST endpoint) ### Parameters - **_type_** (TCppType_t) - The type of the array. ### Response #### Success Response - **return value** (std::vector< long int >) - A vector containing the dimensions of the array. ### Request Example ```cpp std::vector dimensions = cppImplInstance.GetDimensions(_array_type_); ``` ``` -------------------------------- ### GET /api/functions/GetExecutablePath Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppInternal.html Retrieves the executable path. ```APIDOC ## GET /api/functions/GetExecutablePath ### Description Retrieves the executable path. ### Method GET ### Endpoint `/api/functions/GetExecutablePath` ### Response #### Success Response (200) - **path** (string) - The path to the executable. #### Response Example ```json { "path": "/path/to/executable" } ``` ``` -------------------------------- ### Create Build Directory (Windows) Source: https://cppinterop.readthedocs.io/en/latest/InstallationAndUsage.html Creates and navigates into the build directory for CppInterOp on Windows. ```batch mkdir CppInterOp\build\ cd CppInterOp\build\ ``` -------------------------------- ### CppImpl::GetName Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Gets the name of a C++ entity. ```APIDOC ## std::string GetName(TCppScope_t klass) ### Description Gets the name of any named decl (a class, namespace, variable, or a function). ### Definition CppInterOp.cpp:788 ``` -------------------------------- ### Install Firefox on Ubuntu x86 Source: https://cppinterop.readthedocs.io/en/latest/Emscripten-build-instructions.html Download and extract Firefox version 138.0.1 for Ubuntu x86. This sets up the browser in a local directory and exports its path. ```bash wget https://ftp.mozilla.org/pub/firefox/releases/138.0.1/linux-x86_64/en-GB/firefox-138.0.1.tar.xz tar -xJf firefox-138.0.1.tar.xz cd ./firefox export PATH="$PWD:$PATH" cd - ``` -------------------------------- ### GetEnumConstantValue() Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppImpl.html Gets the index value of an enum constant. ```APIDOC ## GetEnumConstantValue() ### Description Gets the index value (0, 1, 2, etcetera) of the enum constant that was passed into this function. ### Method Not specified (likely a member function of CppImpl) ### Endpoint N/A (This is a C++ function, not a REST endpoint) ### Parameters - **_scope_** (TCppScope_t) - The enum constant scope. ### Response #### Success Response - **return value** (TCppIndex_t) - The index value of the enum constant. ### Request Example ```cpp TCppIndex_t enumValue = cppImplInstance.GetEnumConstantValue(_enum_constant_scope_); ``` ``` -------------------------------- ### Navigate to Unit Tests Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Change directory to the unit tests location. ```bash cd ./unittests/CppInterOp/ ``` -------------------------------- ### Run CppInterOpTests on Ubuntu x86 Source: https://cppinterop.readthedocs.io/en/latest/_sources/Emscripten-build-instructions.rst.txt Executes CppInterOpTests and DynamicLibraryManagerTests in Firefox and Google Chrome on Ubuntu x86 using emrun. ```bash echo "Running CppInterOpTests in Firefox" emrun --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" CppInterOpTests.html echo "Running DynamicLibraryManagerTests in Firefox" emrun --browser="firefox" --kill_exit --timeout 60 --browser-args="--headless" DynamicLibraryManagerTests.html echo "Running CppInterOpTests in Google Chrome" emrun --browser="google-chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" CppInterOpTests.html echo "Running DynamicLibraryManagerTests in Google Chrome" emrun --browser="google-chrome" --kill_exit --timeout 60 --browser-args="--headless --no-sandbox" DynamicLibraryManagerTests.html ``` -------------------------------- ### GetEnumConstants() Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppImpl.html Gets a list of all the enum constants for an enum. ```APIDOC ## GetEnumConstants() ### Description Gets a list of all the enum constants for an enum. ### Method Not specified (likely a member function of CppImpl) ### Endpoint N/A (This is a C++ function, not a REST endpoint) ### Parameters - **_scope_** (TCppScope_t) - The enum scope. ### Response #### Success Response - **return value** (std::vector< TCppScope_t >) - A vector containing the enum constants. ### Request Example ```cpp std::vector constants = cppImplInstance.GetEnumConstants(_enum_scope_); ``` ``` -------------------------------- ### Build CppInterOp with Cling (Linux/macOS) Source: https://cppinterop.readthedocs.io/en/latest/InstallationAndUsage.html Configures and builds CppInterOp with Cling on Linux and macOS. Ensure Cling_DIR, LLVM_DIR, CPPINTEROP_DIR environment variables are set. ```bash cmake -DBUILD_SHARED_LIBS=ON -DCPPINTEROP_USE_CLING=ON -DCPPINTEROP_USE_REPL=Off -DCling_DIR=$LLVM_DIR/build/tools/cling -DLLVM_DIR=$LLVM_DIR/build/lib/cmake/llvm -DClang_DIR=$LLVM_DIR/build/lib/cmake/clang -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR .. cmake --build . --target install --parallel $(nproc --all) ``` -------------------------------- ### GetEnumConstantDatamembers() Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppImpl.html Gets all Enum Constants declared in a Class. ```APIDOC ## GetEnumConstantDatamembers() ### Description Gets all the Enum Constants declared in a Class. ### Method Not specified (likely a member function of CppImpl) ### Endpoint N/A (This is a C++ function, not a REST endpoint) ### Parameters - **_scope_** (TCppScope_t) - The class scope. - **_datamembers_** (std::vector< TCppScope_t > &) - Output parameter to store the enum constants. - **_include_enum_class_** (bool) - Optional. If true, includes enum constants from enum class. Defaults to `true`. ### Response #### Success Response void - The enum constants are populated in the _datamembers_ output parameter. ### Request Example ```cpp std::vector enumConstants; cppImplInstance.GetEnumConstantDatamembers(_class_scope_, enumConstants); ``` ``` -------------------------------- ### kind() Source: https://cppinterop.readthedocs.io/en/latest/build/html/CXCppInterOp_8cpp.html Gets the kind of a CXScope. This is a static method. ```APIDOC ## kind() ### Description Gets the kind of a CXScope. ### Method static CXCursorKind ### Endpoint N/A (Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) `CXCursorKind`: The kind of the cursor. #### Response Example None ``` -------------------------------- ### Build Cling and LLVM-Project on Windows Source: https://cppinterop.readthedocs.io/en/latest/DevelopersDocumentation.html These commands are for building Cling and LLVM-project on Windows using PowerShell. They set up environment variables for parallel builds and specify source directories. ```powershell git clone --depth=1 --branch v1.3 https://github.com/root-project/cling.git git clone --depth=1 -b cling-llvm20-20260119-01 https://github.com/root-project/llvm-project.git $env:ncpus = $([Environment]::ProcessorCount) $env:PWD_DIR= $PWD.Path $env:CLING_DIR="$env:PWD_DIR\cling" mkdir llvm-project\build cd llvm-project\build cake -DLLVM_ENABLE_PROJECTS=clang \ -DLLVM_EXTERNAL_PROJECTS=cling \ -DLLVM_EXTERNAL_CLING_SOURCE_DIR="$env:CLING_DIR" \ -DLLVM_TARGETS_TO_BUILD="host;NVPTX" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DCLANG_ENABLE_STATIC_ANALYZER=OFF \ -DCLANG_ENABLE_ARCMT=OFF \ -DCLANG_ENABLE_FORMAT=OFF \ -DCLANG_ENABLE_BOOTSTRAP=OFF \ ../llvm cake --build . --target clang --parallel $env:ncpus cake --build . --target cling --parallel $env:ncpus ``` -------------------------------- ### IsExplicit Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Checks if a C++ deduction guide is explicit. ```APIDOC ## IsExplicit ### Description Checks if a C++ deduction guide is explicit. ### Method N/A (Function Signature) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (bool) - **return value** (bool) - True if the deduction guide is explicit, false otherwise. #### Response Example ```json { "example": "true" } ``` ``` -------------------------------- ### Build CppInterOp with Clang-REPL Source: https://cppinterop.readthedocs.io/en/latest/_sources/DevelopersDocumentation.rst.txt Configure and build CppInterOp using Clang-REPL on different platforms. ```bash cmake -DBUILD_SHARED_LIBS=ON -DLLVM_DIR=$LLVM_DIR/build/lib/cmake/llvm -DClang_DIR=$LLVM_DIR/build/lib/cmake/clang -DCMAKE_INSTALL_PREFIX=$CPPINTEROP_DIR .. cmake --build . --target install --parallel $(nproc --all) ``` ```powershell cmake -DLLVM_DIR=$env:LLVM_DIR\build\lib\cmake\llvm -DClang_DIR=$env:LLVM_DIR\build\lib\cmake\clang -DCMAKE_INSTALL_PREFIX=$env:CPPINTEROP_DIR .. cmake --build . --target install --parallel $env:ncpus ``` -------------------------------- ### Initialize and Get File Descriptors Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOpInterpreter_8h_source.html Initializes temporary files for I/O if not already done and retrieves their file descriptors. Handles potential initialization failures. ```cpp static std::tuple initAndGetFileDescriptors(std::vector& vargs, IOContext& io_ctx) { int stdin_fd = 0; int stdout_fd = 1; int stderr_fd = 2; // Only initialize temp files if not already initialized if (!io_ctx.stdin_file || !io_ctx.stdout_file || !io_ctx.stderr_file) { bool init = io_ctx.initializeTempFiles(); if (!init) { llvm::errs() << "Can't start out-of-process JIT execution.\n"; stdin_fd = -1; stdout_fd = -1; stderr_fd = -1; } } stdin_fd = fileno(io_ctx.stdin_file.get()); stdout_fd = fileno(io_ctx.stdout_file.get()); stderr_fd = fileno(io_ctx.stderr_file.get()); return std::make_tuple(stdin_fd, stdout_fd, stderr_fd); } ``` -------------------------------- ### Detect CUDA Installation Path with Clang Driver Source: https://cppinterop.readthedocs.io/en/latest/build/html/Compatibility_8h_source.html Detects the CUDA installation path by leveraging the Clang driver's internal logic. It handles cases where --cuda-path is provided or attempts auto-detection by looking for internal system include paths. ```cpp #include "clang/Basic/Version.h" #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h" #include #endif #include namespace { /// Detect the CUDA installation path using clang::Driver /// \param args user-provided interpreter arguments (may contain --cuda-path). /// \param[out] CudaPath the detected CUDA installation path. /// \returns true on success, false if not found. inline bool detectCudaInstallPath(const std::vector& args, std::string& CudaPath) { // minimal driver that runs CudaInstallationDetector internally std::string TT = llvm::sys::getProcessTriple(); llvm::IntrusiveRefCntPtr DiagID( new clang::DiagnosticIDs()); // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) auto* DiagsBuffer = new clang::TextDiagnosticBuffer; #if CLANG_VERSION_MAJOR < 21 llvm::IntrusiveRefCntPtr DiagOpts( new clang::DiagnosticOptions()); clang::DiagnosticsEngine Diags(DiagID, DiagOpts, DiagsBuffer); #else clang::DiagnosticOptions DiagOpts; clang::DiagnosticsEngine Diags(DiagID, DiagOpts, DiagsBuffer); #endif clang::driver::Driver D("clang", TT, Diags); D.setCheckInputsExist(false); // construct args: clang -x cuda -c <<< inputs >>> [args] llvm::SmallVector Argv; Argv.push_back("clang"); Argv.push_back("-xcuda"); Argv.push_back("-c"); Argv.push_back("<<< inputs >>>"); for (const auto* arg : args) Argv.push_back(arg); // build a compilation object, which runs the driver's CUDA installation // detection logic and stores the paths std::unique_ptr C(D.BuildCompilation(Argv)); if (!C) return false; // --cuda-path was explicitly provided in user args if (auto* A = C->getArgs().getLastArg(clang::driver::options::OPT_cuda_path_EQ)) { std::string Candidate = A->getValue(); if (llvm::sys::fs::is_directory(Candidate + "/include")) { CudaPath = Candidate; return true; } } // fallback: clang tries to auto-detect the install, CudaInstallationDetector // stores the path internally but doesn't expose it, so we look for // "-internal-isystem /include" that the driver adds for CUDA // headers. for (const auto& Job : C->getJobs()) { if (const auto* Cmd = llvm::dyn_cast(&Job)) { const auto& Args = Cmd->getArguments(); for (size_t i = 0; i + 1 < Args.size(); ++i) { if (llvm::StringRef(Args[i]) == "-internal-isystem") { llvm::StringRef IncDir(Args[i + 1]); if (IncDir.ends_with("/include") && llvm::sys::fs::exists(IncDir.str() + "/cuda.h")) { CudaPath = IncDir.drop_back(strlen("/include")).str(); return true; } } } } } return false; } ``` -------------------------------- ### Initialize Conda Environment Source: https://cppinterop.readthedocs.io/en/latest/Emscripten-build-instructions.html Create and activate a Conda environment for the WebAssembly build. ```bash cd ../../CppInterOp/ micromamba create -f environment-wasm.yml --platform=emscripten-wasm32 -c https://prefix.dev/emscripten-forge-4x -c https://prefix.dev/conda-forge micromamba activate CppInterOp-wasm ``` -------------------------------- ### CppImpl::GetTypeInternal Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Internal function to get type information. ```APIDOC ## static std::optional< QualType > GetTypeInternal(Decl *D) ### Description Internal function to get type information. ### Definition CppInterOp.cpp:2278 ``` -------------------------------- ### CppImpl::GetFunctionNumArgs Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Gets the number of arguments for a given function. ```APIDOC ## TCppIndex_t GetFunctionNumArgs(TCppFunction_t func) ### Description Gets the number of Arguments for the provided function. ### Definition CppInterOp.cpp:1316 ``` -------------------------------- ### Initialize DynamicLibraryManager Source: https://cppinterop.readthedocs.io/en/latest/build/html/DynamicLibraryManager_8cpp_source.html The constructor initializes library search paths by parsing environment variables like LD_LIBRARY_PATH, PATH, or DYLD_LIBRARY_PATH, and appending system-specific library paths. ```cpp DynamicLibraryManager::DynamicLibraryManager() { const SmallVector kSysLibraryEnv = { "LD_LIBRARY_PATH", #if __APPLE__ "DYLD_LIBRARY_PATH", "DYLD_FALLBACK_LIBRARY_PATH", /* "DYLD_VERSIONED_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH", "DYLD_FALLBACK_FRAMEWORK_PATH", "DYLD_VERSIONED_FRAMEWORK_PATH", */ #elif defined(_WIN32) "PATH", #endif }; // Behaviour is to not add paths that don't exist...In an interpreted env // does this make sense? Path could pop into existence at any time. for (const char* Var : kSysLibraryEnv) { if (const char* Env = GetEnv(Var)) { SmallVector CurPaths; SplitPaths(Env, CurPaths, SplitMode::kPruneNonExistent, platform::kEnvDelim); for (const auto& Path : CurPaths) addSearchPath(Path); } } // $CWD is the last user path searched. addSearchPath("."); SmallVector SysPaths; platform::GetSystemLibraryPaths(SysPaths); for (const std::string& P : SysPaths) addSearchPath(P, /*IsUser*/ false); } ``` -------------------------------- ### Build Cling on Linux and MacOS Source: https://cppinterop.readthedocs.io/en/latest/InstallationAndUsage.html Commands to clone the repository and build Cling using CMake on Unix-like systems. ```bash git clone --depth=1 --branch v1.3 https://github.com/root-project/cling.git git clone --depth=1 -b cling-llvm20-20260119-01 https://github.com/root-project/llvm-project.git mkdir llvm-project/build cd llvm-project/build cmake -DLLVM_ENABLE_PROJECTS=clang \ -DLLVM_EXTERNAL_PROJECTS=cling \ -DLLVM_EXTERNAL_CLING_SOURCE_DIR=../../cling \ -DLLVM_TARGETS_TO_BUILD="host;NVPTX" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DCLANG_ENABLE_STATIC_ANALYZER=OFF \ -DCLANG_ENABLE_ARCMT=OFF \ -DCLANG_ENABLE_FORMAT=OFF \ -DCLANG_ENABLE_BOOTSTRAP=OFF \ ../llvm cmake --build . --target clang --parallel $(nproc --all) cmake --build . --target cling --parallel $(nproc --all) ``` -------------------------------- ### CppImpl::GetStaticDatamembers Source: https://cppinterop.readthedocs.io/en/latest/build/html/CppInterOp_8cpp_source.html Gets all the Static Fields/Data Members of a Class. ```APIDOC ## GetStaticDatamembers ### Description Gets all the Static Fields/Data Members of a Class. ### Parameters - **scope** (TCppScope_t) - Required - The class scope. - **datamembers** (std::vector&) - Required - Output vector to store the data members. ``` -------------------------------- ### Build Cling on Windows Source: https://cppinterop.readthedocs.io/en/latest/InstallationAndUsage.html Commands to clone the repository and build Cling using PowerShell and CMake on Windows. ```powershell git clone --depth=1 --branch v1.3 https://github.com/root-project/cling.git git clone --depth=1 -b cling-llvm20-20260119-01 https://github.com/root-project/llvm-project.git $env:ncpus = $([Environment]::ProcessorCount) $env:PWD_DIR= $PWD.Path $env:CLING_DIR="$env:PWD_DIR\cling" mkdir llvm-project\build cd llvm-project\build cmake -DLLVM_ENABLE_PROJECTS=clang ` -DLLVM_EXTERNAL_PROJECTS=cling ` -DLLVM_EXTERNAL_CLING_SOURCE_DIR="$env:CLING_DIR" ` -DLLVM_TARGETS_TO_BUILD="host;NVPTX" ` -DCMAKE_BUILD_TYPE=Release ` -DLLVM_ENABLE_ASSERTIONS=ON ` -DCLANG_ENABLE_STATIC_ANALYZER=OFF ` -DCLANG_ENABLE_ARCMT=OFF ` -DCLANG_ENABLE_FORMAT=OFF ` -DCLANG_ENABLE_BOOTSTRAP=OFF ` ../llvm cmake --build . --target clang --parallel $env:ncpus cmake --build . --target cling --parallel $env:ncpus ``` -------------------------------- ### GetEnumConstantType() Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppImpl.html Gets the enum name when an enum constant is passed. ```APIDOC ## GetEnumConstantType() ### Description Gets the enum name when an enum constant is passed. ### Method Not specified (likely a member function of CppImpl) ### Endpoint N/A (This is a C++ function, not a REST endpoint) ### Parameters - **_scope_** (TCppScope_t) - The enum constant scope. ### Response #### Success Response - **return value** (TCppType_t) - The type (name) of the enum. ### Request Example ```cpp TCppType_t enumType = cppImplInstance.GetEnumConstantType(_enum_constant_scope_); ``` ``` -------------------------------- ### CppInterOp::Tracing::TraceInfo::StartRegion() Source: https://cppinterop.readthedocs.io/en/latest/build/html/classCppInterOp_1_1Tracing_1_1TraceInfo.html Begins a traced region. ```APIDOC ## std::string CppInterOp::Tracing::TraceInfo::StartRegion() ### Description Begins a new traced region. Returns the path where the `StopRegion` function will write. ### Method std::string ### Endpoint N/A (Class method) ### Parameters None ### Request Example N/A ### Response #### Success Response (200) - **std::string**: The path for the stop region operation. ``` -------------------------------- ### AddSearchPath() Source: https://cppinterop.readthedocs.io/en/latest/build/html/namespaceCppImpl.html Adds a search path for the Interpreter to get the libraries. ```APIDOC ## ◆ AddSearchPath() void CppImpl::AddSearchPath | ( | const char * | _dir_ , | | bool | _isUser_ = `true`, | | bool | _prepend_ = `false` | ) Adds a Search Path for the Interpreter to get the libraries. Definition at line 3850 of file CppInterOp.cpp. References CppInternal::DynamicLibraryManager::addSearchPath(), GetClassDecls(), CppInternal::Interpreter::getDynamicLibraryManager(), getInterp(), INTEROP_TRACE, and INTEROP_VOID_RETURN. ```