From 1ab59f6143813be9d5eed60e78791e64ff846993 Mon Sep 17 00:00:00 2001 From: Fernando Pelliccioni Date: Fri, 26 Jul 2024 16:57:05 -0300 Subject: [PATCH] Standard library incompatibility fix by packaging libc++ --- .github/workflows/ci.yml | 123 +++++++++++++++------- .gitignore | 4 +- CMakeLists.txt | 19 +++- docs/modules/ROOT/pages/install.adoc | 94 ++++++++++++++++- docs/website/render.js | 4 +- src/lib/Lib/ConfigOptions.json | 22 ++++ src/lib/Lib/MrDocsCompilationDatabase.cpp | 55 +++++++--- src/lib/Metadata/Finalize.cpp | 1 + src/test/TestArgs.cpp | 10 ++ src/test/TestArgs.hpp | 2 + src/tool/StdLib.cpp | 59 +++++++++++ src/tool/StdLib.hpp | 33 ++++++ src/tool/ToolArgs.cpp | 1 + 13 files changed, 372 insertions(+), 55 deletions(-) create mode 100644 src/tool/StdLib.cpp create mode 100644 src/tool/StdLib.hpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d037b71cb..0caaec727 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -104,9 +104,9 @@ jobs: cd fmt cmake -S . -B ./build -D FMT_DOC=OFF -D FMT_TEST=OFF -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DCMAKE_CXX_COMPILER=${{ steps.setup-cpp.outputs.cxx }} -DCMAKE_C_COMPILER=${{ steps.setup-cpp.outputs.cc }} N_CORES=$(nproc 2>/dev/null || echo 1) - cmake --build ./build --config ${{ matrix.build-type }} --parallel $N_CORES + cmake --build ./build --config ${{ matrix.build-type }} --parallel $N_CORES cmake --install ./build --prefix ./install - + fmt_root=$(pwd)/install if [[ ${{ runner.os }} == 'Windows' ]]; then fmt_root=$(echo "$fmt_root" | sed 's/\\/\//g') @@ -135,9 +135,9 @@ jobs: fi cmake -S . -B ./build -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DCMAKE_CXX_COMPILER=${{ steps.setup-cpp.outputs.cxx }} -DCMAKE_C_COMPILER=${{ steps.setup-cpp.outputs.cc }} N_CORES=$(nproc 2>/dev/null || echo 1) - cmake --build ./build --config ${{ matrix.build-type }} --parallel $N_CORES + cmake --build ./build --config ${{ matrix.build-type }} --parallel $N_CORES cmake --install ./build --prefix ./install - + duktape_root=$(pwd)/install if [[ ${{ runner.os }} == 'Windows' ]]; then duktape_root=$(echo "$duktape_root" | sed 's/\\/\//g') @@ -159,12 +159,12 @@ jobs: git config --global advice.detachedHead false git clone https://github.com/GNOME/libxml2 --branch v2.12.6 --depth 1 cd libxml2 - + cmake -S . -B ./build -DCMAKE_BUILD_TYPE=Release -DLIBXML2_WITH_PROGRAMS=ON -DLIBXML2_WITH_FTP=OFF -DLIBXML2_WITH_HTTP=OFF -DLIBXML2_WITH_ICONV=OFF -DLIBXML2_WITH_LEGACY=OFF -DLIBXML2_WITH_LZMA=OFF -DLIBXML2_WITH_ZLIB=OFF -DLIBXML2_WITH_ICU=OFF -DLIBXML2_WITH_TESTS=OFF -DLIBXML2_WITH_HTML=ON -DLIBXML2_WITH_C14N=ON -DLIBXML2_WITH_CATALOG=ON -DLIBXML2_WITH_DEBUG=ON -DLIBXML2_WITH_ISO8859X=ON -DLIBXML2_WITH_MEM_DEBUG=OFF -DLIBXML2_WITH_MODULES=ON -DLIBXML2_WITH_OUTPUT=ON -DLIBXML2_WITH_PATTERN=ON -DLIBXML2_WITH_PUSH=ON -DLIBXML2_WITH_PYTHON=OFF -DLIBXML2_WITH_READER=ON -DLIBXML2_WITH_REGEXPS=ON -DLIBXML2_WITH_SAX1=ON -DLIBXML2_WITH_SCHEMAS=ON -DLIBXML2_WITH_SCHEMATRON=ON -DLIBXML2_WITH_THREADS=ON -DLIBXML2_WITH_THREAD_ALLOC=OFF -DLIBXML2_WITH_TREE=ON -DLIBXML2_WITH_VALID=ON -DLIBXML2_WITH_WRITER=ON -DLIBXML2_WITH_XINCLUDE=ON -DLIBXML2_WITH_XPATH=ON -DLIBXML2_WITH_XPTR=ON -DCMAKE_CXX_COMPILER=${{ steps.setup-cpp.outputs.cxx || steps.parameters.outputs.clang-bin }} -DCMAKE_C_COMPILER=${{ steps.setup-cpp.outputs.cc || steps.parameters.outputs.clang-bin }} N_CORES=$(nproc 2>/dev/null || echo 1) - cmake --build ./build --config ${{ matrix.build-type }} --parallel $N_CORES + cmake --build ./build --config ${{ matrix.build-type }} --parallel $N_CORES cmake --install ./build --prefix ./install - + libxml2_root=$(pwd)/install if [[ ${{ runner.os }} == 'Windows' ]]; then libxml2_root=$(echo "$libxml2_root" | sed 's/\\/\//g') @@ -173,6 +173,7 @@ jobs: fi echo -E "libxml2-root=$libxml2_root" >> $GITHUB_OUTPUT + - name: LLVM Parameters id: llvm-parameters run: | @@ -188,6 +189,14 @@ jobs: fi echo -E "llvm-root=$llvm_root" >> $GITHUB_OUTPUT + libcxx_root=$(pwd)/third-party/llvm-project/install + if [[ ${{ runner.os }} == 'Windows' ]]; then + libcxx_root=$(echo "$libcxx_root" | sed 's/\\/\//g') + libcxx_root=$(echo $libcxx_root | sed 's|^/d/|D:/|') + echo "$libcxx_root" + fi + echo -E "libcxx-root=$libcxx_root" >> $GITHUB_OUTPUT + - name: LLVM Binaries id: llvm-cache uses: actions/cache@v4 @@ -202,7 +211,7 @@ jobs: run: | # LLVM is be installed with the default compiler set -x - + # Shallow clone LLVM_HASH in ../third-party/llvm cd .. mkdir -p third-party/llvm-project @@ -218,7 +227,7 @@ jobs: # Copy presets cp ../../mrdocs/third-party/llvm/CMakePresets.json ./llvm cp ../../mrdocs/third-party/llvm/CMakeUserPresets.json.example ./llvm/CMakeUserPresets.json - + # Build cd llvm llvm_root=$(pwd) @@ -226,11 +235,68 @@ jobs: cmake -S . -B ./build --preset=${{ steps.llvm-parameters.outputs.llvm-build-preset }} -DCMAKE_CXX_COMPILER=${{ steps.setup-cpp.outputs.cxx }} -DCMAKE_C_COMPILER=${{ steps.setup-cpp.outputs.cc }} if [[ ${{ runner.os }} == 'Linux' ]]; then cmake --build ./build --target help - fi + fi N_CORES=$(nproc 2>/dev/null || echo 1) cmake --build ./build --config Release --parallel $N_CORES cmake --install ./build --prefix "$llvm_project_root"/install + - name: LibC++ Binaries + id: libcxx-cache + uses: actions/cache@v4 + with: + path: ${{ steps.llvm-parameters.outputs.libcxx-root }} + key: libcxx-${{ runner.os }}-${{ matrix.compiler }}-${{ matrix.version }}-${{ steps.llvm-parameters.outputs.llvm-hash }} + + - name: Install LibC++ + id: libcxx-install + if: ${{ steps.libcxx-cache.outputs.cache-hit != 'true'}} + shell: bash + run: | + set -x + + cd .. + llvm_project_root="$(pwd)/third-party/llvm-project" + if [ ! -d "$llvm_project_root/runtimes" ]; then + mkdir -p $llvm_project_root + cd $llvm_project_root + git config --global init.defaultBranch master + git config --global advice.detachedHead false + git init + git remote add origin https://github.com/llvm/llvm-project.git + git fetch --depth 1 origin ${{ steps.llvm-parameters.outputs.llvm-hash }} + git checkout FETCH_HEAD + fi + + export CXX="$llvm_project_root/install/bin/clang++" + export CC="$llvm_project_root/install/bin/clang" + + cd $llvm_project_root + + if [ ${{ runner.os }} != 'Windows' ]; then + cmake -G Ninja \ + -S runtimes \ + -B build-libcxx \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ + -DCMAKE_INSTALL_PREFIX="$llvm_project_root/install" + + ninja -C build-libcxx cxx cxxabi unwind + ninja -C build-libcxx install-cxx install-cxxabi install-unwind + else + cmake -G Ninja \ + -S runtimes \ + -B build-libcxx \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + -DCMAKE_INSTALL_PREFIX="$llvm_project_root/install" \ + -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ + -DLIBCXXABI_ENABLE_SHARED=OFF \ + -DLIBCXXABI_ENABLE_STATIC=ON \ + -DLIBCXX_ENABLE_SHARED=OFF \ + -DLIBCXX_NO_VCRUNTIME=ON \ + -DCMAKE_CXX_FLAGS="-D__ORDER_LITTLE_ENDIAN__=1234 -D__ORDER_BIG_ENDIAN__=4321 -D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__" + ninja -C build-libcxx cxx + ninja -C build-libcxx install-cxx + fi + - name: Install Node.js uses: actions/setup-node@v3 with: @@ -256,7 +322,7 @@ jobs: -D duktape_ROOT=${{ steps.duktape-install.outputs.duktape-root }} -D Duktape_ROOT=${{ steps.duktape-install.outputs.duktape-root }} -D fmt_ROOT=${{ steps.fmt-install.outputs.fmt-root }} - ${{ (steps.libxml2-install.outputs.libxml2-root && format('-D libxml2_ROOT={0}', steps.libxml2-install.outputs.libxml2-root)) || '' }} + ${{ (steps.libxml2-install.outputs.libxml2-root && format('-D libxml2_ROOT={0}', steps.libxml2-install.outputs.libxml2-root)) || '' }} ${{ (steps.libxml2-install.outputs.libxml2-root && format('-D LibXml2_ROOT={0}', steps.libxml2-install.outputs.libxml2-root)) || '' }} export-compile-commands: true run-tests: true @@ -296,27 +362,17 @@ jobs: run: shell: bash name: Website - timeout-minutes: 30 - runs-on: ubuntu-20.04 - container: ubuntu:23.04 + timeout-minutes: 30 + runs-on: ubuntu-latest + container: ubuntu:20.04 permissions: contents: write steps: - - name: Setup C++ - uses: alandefreitas/cpp-actions/setup-cpp@v1.8.3 - id: setup-cpp - with: - compiler: clang - version: 16 - check-latest: true - - name: Install packages uses: alandefreitas/cpp-actions/package-install@v1.8.3 id: package-install with: - apt-get: libstdc++-12-dev asciidoctor cmake bzip2 git - cc: ${{ steps.setup-cpp.outputs.cc }} - cxx: ${{ steps.setup-cpp.outputs.cxx }} + apt-get: build-essential asciidoctor cmake bzip2 git - name: Clone mrdocs uses: actions/checkout@v4 @@ -339,8 +395,6 @@ jobs: mrdocs --version MRDOCS_ROOT=/usr/local echo -e "MRDOCS_ROOT=$MRDOCS_ROOT" >> $GITHUB_ENV - CXX=/usr/bin/clang-16 - echo -e "CXX=$CXX" >> $GITHUB_ENV - name: Clone Boost.URL uses: alandefreitas/cpp-actions/boost-clone@v1.8.3 @@ -393,11 +447,6 @@ jobs: - name: Generate Demos run: | - CXX="${{ steps.setup-cpp.outputs.cxx }}" - export CXX - CC="${{ steps.setup-cpp.outputs.cc }}" - export CC - declare -a generators=( "adoc" "xml" @@ -438,15 +487,15 @@ jobs: id: compare-demos run: | set -x - + # Define URLs and directories LOCAL_DEMOS_DIR="./demos/" PREV_DEMOS_DIR="./demos-previous/" DIFF_DIR="./demos-diff/" - + # Create directories if they don't exist mkdir -p $PREV_DEMOS_DIR $DIFF_DIR - + # Iterate over the previous files and compare them with the corresponding local files find $PREV_DEMOS_DIR -type f | while read previous_file; do # Derive the corresponding local file path @@ -464,7 +513,7 @@ jobs: cat "$previous_file" >> "$diff_output" fi done - + # Iterate over the local files to find new files find $LOCAL_DEMOS_DIR -type f | while read local_file; do previous_file="${PREV_DEMOS_DIR}${local_file#$LOCAL_DEMOS_DIR}" @@ -475,7 +524,7 @@ jobs: echo "NEW CONTENT OF THE FILE IS:" >> "$diff_output" fi done - + # Check if the diff directory is empty if [[ -z $(ls -A $DIFF_DIR) ]]; then echo "No differences found." diff --git a/.gitignore b/.gitignore index 2a85a591d..b396488a2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ /test-files/**/*.adoc /test-files/**/*.bad.xml docs/node_modules -docs/build \ No newline at end of file +docs/build +share/mrdocs/libcxx/ +share/mrdocs/clang/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 760f53824..fd67d7c4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,12 @@ elseif (LLVM_ROOT) endif() find_package(LLVM REQUIRED CONFIG) find_package(Clang REQUIRED CONFIG) + +if (LLVM_ROOT) + set(LIBCXX_DIR "${LLVM_ROOT}/include/c++/v1/") + set(STDLIB_INCLUDE_DIR "${LLVM_ROOT}/lib/clang/${Clang_VERSION_MAJOR}/include/") +endif() + list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") include(HandleLLVMOptions) add_definitions(${LLVM_DEFINITIONS}) @@ -337,7 +343,9 @@ if (MRDOCS_BUILD_TESTS) --unit=false --action=test "${PROJECT_SOURCE_DIR}/test-files/golden-tests" - --addons="${CMAKE_SOURCE_DIR}/share/mrdocs/addons") + --addons="${CMAKE_SOURCE_DIR}/share/mrdocs/addons" + --system-includes="${LIBCXX_DIR}" + --system-includes="${STDLIB_INCLUDE_DIR}") foreach (action IN ITEMS create update) add_custom_target( mrdocs-${action}-test-fixtures @@ -347,6 +355,8 @@ if (MRDOCS_BUILD_TESTS) --action=${action} "${PROJECT_SOURCE_DIR}/test-files/golden-tests" --addons="${CMAKE_SOURCE_DIR}/share/mrdocs/addons" + --system-includes="${LIBCXX_DIR}" + --system-includes="${STDLIB_INCLUDE_DIR}" DEPENDS mrdocs-test ) endforeach () @@ -492,6 +502,13 @@ if (MRDOCS_INSTALL) #------------------------------------------------- # share #------------------------------------------------- + install(DIRECTORY ${LIBCXX_DIR} + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mrdocs/libcxx + FILES_MATCHING PATTERN "*") + install(DIRECTORY ${STDLIB_INCLUDE_DIR} + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mrdocs/clang + FILES_MATCHING PATTERN "*") + foreach (share_mrdocs_dir addons) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/share/mrdocs/${share_mrdocs_dir} DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mrdocs diff --git a/docs/modules/ROOT/pages/install.adoc b/docs/modules/ROOT/pages/install.adoc index e71887d68..c7eba42cb 100644 --- a/docs/modules/ROOT/pages/install.adoc +++ b/docs/modules/ROOT/pages/install.adoc @@ -382,12 +382,102 @@ cmake --install ./build --prefix ../install Replace 4 with the number of cores you want to use for building LLVM. -Return from `./third-party/llvm-project/llvm` to the parent directory to build and install MrDocs: +Return from `./third-party/llvm-project/llvm` to the LLVM project directory: [source,bash] ---- -cd ../../.. +cd ../.. +---- + +=== LibC++ + +In addition to LLVM, MrDocs requires a deterministic version of the C++ standard library (LibC++) to ensure consistent behavior across various environments. This step is crucial for replicating specific compiler and library configurations. + +**Download**: + +Continue using the same LLVM project directory. + +**Configure**: + +Configure and build LibC++ using the existing structure: + +[source,bash] +---- +export CXX="./install/bin/clang++" +export CC="./install/bin/clang" +---- + +Run a command such as the following to configure LLVM: + +[tabs] +==== +Windows PowerShell:: ++ +-- +[source,bash] +---- +cmake -G Ninja \ + -S runtimes \ + -B build-libcxx \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + -DCMAKE_INSTALL_PREFIX="$(pwd)/install" \ + -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ + -DLIBCXXABI_ENABLE_SHARED=OFF \ + -DLIBCXXABI_ENABLE_STATIC=ON \ + -DLIBCXX_ENABLE_SHARED=OFF \ + -DLIBCXX_NO_VCRUNTIME=ON \ + -DCMAKE_CXX_FLAGS="-D__ORDER_LITTLE_ENDIAN__=1234 -D__ORDER_BIG_ENDIAN__=4321 -D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__" +---- +-- + +Unix Variants:: ++ +-- +[source,bash] +---- +cmake -G Ninja \ + -S runtimes \ + -B build-libcxx \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ + -DCMAKE_INSTALL_PREFIX="$(pwd)/install" ---- +-- +==== + +**Build**: + +Build and install the configured version of LibC++ with: + +[tabs] +==== +Windows PowerShell:: ++ +-- +[source,bash] +---- +ninja -C build-libcxx cxx +ninja -C build-libcxx install-cxx +---- +-- + +Unix Variants:: ++ +-- +[source,bash] +---- +ninja -C build-libcxx cxx cxxabi unwind +ninja -C build-libcxx install-cxx install-cxxabi install-unwind +---- +-- +==== + +Return from `./third-party/llvm-project` to the parent directory to build and install MrDocs: + +[source,bash] +---- +cd ../.. +---- + === MrDocs diff --git a/docs/website/render.js b/docs/website/render.js index c63400b04..9c7dfedd5 100644 --- a/docs/website/render.js +++ b/docs/website/render.js @@ -57,7 +57,8 @@ for (let panel of data.panels) { // Create a CMakeLists.txt file for the snippet const cmakeListsPath = path.join(absSnippetsDir, 'CMakeLists.txt') - fs.writeFileSync(cmakeListsPath, `cmake_minimum_required(VERSION 3.13)\nproject(${sourceBasename})\nadd_executable(${sourceBasename} ${panel.source})\n`) + const cmakeListsContent = `cmake_minimum_required(VERSION 3.13)\nproject(${sourceBasename})\nadd_executable(${sourceBasename} ${panel.source})\n` + fs.writeFileSync(cmakeListsPath, cmakeListsContent) // Run mrdocs to generate documentation const mrdocsConfig = path.join(absSnippetsDir, 'mrdocs.yml') @@ -65,6 +66,7 @@ for (let panel of data.panels) { const mrdocsOutput = path.join(absSnippetsDir, 'output') const command = `${mrdocsExecutable} --config=${mrdocsConfig} ${mrdocsInput} --output=${mrdocsOutput} --multipage=true --generate=adoc` console.log(`Running command: ${command}`) + console.log(`for: ${cmakeListsContent}`) execSync(command, {encoding: 'utf8'}); // Look for documentation file somewhere in the output directory diff --git a/src/lib/Lib/ConfigOptions.json b/src/lib/Lib/ConfigOptions.json index 32cf3abb1..6f4a92d6b 100644 --- a/src/lib/Lib/ConfigOptions.json +++ b/src/lib/Lib/ConfigOptions.json @@ -79,6 +79,28 @@ "details": "Additional defines passed to the compiler when building the source code. These defines are added to the compilation database regardless of the strategy to generate it.", "type": "list", "default": [] + }, + { + "name": "use-system-stdlib", + "brief": "Use the system standard library", + "details": "True if the compiler has to use just the system standard library. When set to true, the compiler uses the system standard library instead of the standard library provided by the compiler.", + "type": "bool", + "default": false + }, + { + "name": "system-includes", + "brief": "Standard Library include paths", + "details": "Standard Library include paths.", + "type": "list", + "default": ["/share/mrdocs/libcxx", "/share/mrdocs/clang"], + "relativeto": "" + }, + { + "name": "includes", + "brief": "Additional include paths", + "details": "Additional include paths.", + "type": "list", + "default": [] } ] }, diff --git a/src/lib/Lib/MrDocsCompilationDatabase.cpp b/src/lib/Lib/MrDocsCompilationDatabase.cpp index 21d271569..0d1e17ec4 100644 --- a/src/lib/Lib/MrDocsCompilationDatabase.cpp +++ b/src/lib/Lib/MrDocsCompilationDatabase.cpp @@ -245,7 +245,10 @@ adjustCommandLine( llvm::StringRef workingDir, const std::vector& cmdline, const std::vector& additional_defines, - std::unordered_map> const& implicitIncludeDirectories) + std::unordered_map> const& implicitIncludeDirectories, + std::vector const& systemIncludes, + std::vector const& includes, + bool useSystemStdLib) { if (cmdline.empty()) { @@ -297,19 +300,42 @@ adjustCommandLine( new_cmdline.emplace_back(fmt::format("-D{}", def)); } - // ------------------------------------------------------ - // Add implicit include paths - // ------------------------------------------------------ - // Implicit include paths are those which are automatically - // added by the compiler. These will not be defined in the - // compile command, so we add them here so that clang - // can also find these headers. - if (auto it = implicitIncludeDirectories.find(progName); - it != implicitIncludeDirectories.end()) { - for (auto const& inc : it->second) + if (useSystemStdLib) + { + // ------------------------------------------------------ + // Add implicit include paths + // ------------------------------------------------------ + // Implicit include paths are those which are automatically + // added by the compiler. These will not be defined in the + // compile command, so we add them here so that clang + // can also find these headers. + if (auto const it = implicitIncludeDirectories.find(progName); + it != implicitIncludeDirectories.end()) { + for (auto const& inc : it->second) + { + new_cmdline.emplace_back(fmt::format("-isystem{}", inc)); + } + } + } + else + { + // ------------------------------------------------------ + // Add standard library include directories + // ------------------------------------------------------ + for (auto const& inc : systemIncludes) { - new_cmdline.emplace_back(fmt::format("-I{}", inc)); + new_cmdline.emplace_back(fmt::format("-isystem{}", inc)); } + new_cmdline.emplace_back("-nostdinc++"); + new_cmdline.emplace_back("-nostdlib++"); + } + + // ------------------------------------------------------ + // Add additional include directories + // ------------------------------------------------------ + for (auto const& inc : includes) + { + new_cmdline.emplace_back(fmt::format("-I{}", inc)); } // ------------------------------------------------------ @@ -390,7 +416,10 @@ MrDocsCompilationDatabase( workingDir, cmd0.CommandLine, (*config_impl)->defines, - implicitIncludeDirectories); + implicitIncludeDirectories, + (*config_impl)->systemIncludes, + (*config_impl)->includes, + (*config_impl)->useSystemStdlib); cmd.Directory = makeAbsoluteAndNative(workingDir, cmd0.Directory); cmd.Filename = makeAbsoluteAndNative(workingDir, cmd0.Filename); if (isCXXSrcFile(cmd.Filename)) diff --git a/src/lib/Metadata/Finalize.cpp b/src/lib/Metadata/Finalize.cpp index cc3daaa9f..1036e6705 100644 --- a/src/lib/Metadata/Finalize.cpp +++ b/src/lib/Metadata/Finalize.cpp @@ -12,6 +12,7 @@ #include "lib/Lib/Info.hpp" #include "lib/Support/NameParser.hpp" #include +#include #include #include diff --git a/src/test/TestArgs.cpp b/src/test/TestArgs.cpp index 7f6c6da4a..96687cb3e 100644 --- a/src/test/TestArgs.cpp +++ b/src/test/TestArgs.cpp @@ -80,6 +80,16 @@ R"( "addons", llvm::cl::desc("The directory with the addons."), llvm::cl::cat(commonCat)) + +, systemIncludes( + "system-includes", + llvm::cl::desc("A list of paths to the system headers."), + llvm::cl::cat(commonCat)) + +, includes( + "includes", + llvm::cl::desc("A list of paths to additional include directories."), + llvm::cl::cat(commonCat)) { } diff --git a/src/test/TestArgs.hpp b/src/test/TestArgs.hpp index 6a9c20288..17407761b 100644 --- a/src/test/TestArgs.hpp +++ b/src/test/TestArgs.hpp @@ -47,6 +47,8 @@ class TestArgs llvm::cl::opt unitOption; llvm::cl::list inputPaths; llvm::cl::opt addons; + llvm::cl::list systemIncludes; + llvm::cl::list includes; // Hide all options that don't belong to us void hideForeignOptions(); diff --git a/src/tool/StdLib.cpp b/src/tool/StdLib.cpp new file mode 100644 index 000000000..9c4666d78 --- /dev/null +++ b/src/tool/StdLib.cpp @@ -0,0 +1,59 @@ +// +// Licensed 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 +// +// Copyright (c) 2024 Fernando Pelliccioni (fpelliccioni@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdocs +// + +#include "StdLib.hpp" +#include +#include +#include +#include + +namespace clang { +namespace mrdocs { + +Expected +setupStdLibDirs( + std::vector& stdLibDirsArg, + std::string_view execPath) +{ + if (stdLibDirsArg.empty()) + { + MRDOCS_CHECK(execPath, "getMainExecutable failed"); + + // Set LibC++ path from process working directory + std::string binDir = files::getParentDir(execPath); + { + std::string stdLibDir = files::makeDirsy(files::appendPath( + binDir, "..", "share", "mrdocs", "libcxx")); + report::info("Adding libcxx stdlib dir: {}", stdLibDir); + Error err = files::requireDirectory(stdLibDir); + MRDOCS_CHECK(err); + stdLibDirsArg.push_back(stdLibDir); + } + { + std::string clangDir = files::makeDirsy(files::appendPath( + binDir, "..", "share", "mrdocs", "clang")); + report::info("Adding clang stdlib dir: {}", clangDir); + Error err = files::requireDirectory(clangDir); + MRDOCS_CHECK(err); + stdLibDirsArg.push_back(clangDir); + } + } + else + { + for (auto& path : stdLibDirsArg) + { + path = files::makeDirsy(files::normalizePath(path)); + } + } + return {}; +} + +} // mrdocs +} // clang diff --git a/src/tool/StdLib.hpp b/src/tool/StdLib.hpp new file mode 100644 index 000000000..3e4375342 --- /dev/null +++ b/src/tool/StdLib.hpp @@ -0,0 +1,33 @@ +// +// Licensed 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 +// +// Copyright (c) 2024 Fernando Pelliccioni (fpelliccioni@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdocs +// + +#ifndef MRDOCS_TOOL_STDLIB_HPP +#define MRDOCS_TOOL_STDLIB_HPP + +#include +#include +#include + +namespace clang { +namespace mrdocs { + +/** Set the StdLib directories using the argument as a hint. + + @return The error if any occurred. +*/ +Expected +setupStdLibDirs( + std::vector& stdLibDirsArg, + std::string_view execPath); + +} // mrdocs +} // clang + +#endif // MRDOCS_TOOL_STDLIB_HPP diff --git a/src/tool/ToolArgs.cpp b/src/tool/ToolArgs.cpp index c1d902a5a..1bfa92f92 100644 --- a/src/tool/ToolArgs.cpp +++ b/src/tool/ToolArgs.cpp @@ -10,6 +10,7 @@ #include "ToolArgs.hpp" #include "Addons.hpp" +#include "StdLib.hpp" #include #include #include