Skip to content

ci: enable macos and blocking issues #697

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 10, 2024
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
83 changes: 63 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,26 @@ jobs:
gcc 14
clang 18
msvc >=14.40
apple-clang *
standards: '20'
latest-factors: ''
factors: |
latest-factors: |
msvc Optimized-Debug
factors: ''
runs-on: |
apple-clang: macos-15
build-types: |
gcc: Release
clang: Release
apple-clang: Release
msvc: RelWithDebInfo
msvc Optimized-Debug: Debug
ccflags: |
msvc Optimized-Debug: /Ob1 /O2 /Zi
cxxflags: |
msvc Optimized-Debug: /Ob1 /O2 /Zi
install: |
gcc: git build-essential pkg-config python3 curl openjdk-11-jdk ninja-build pkg-config libncurses-dev libxml2-utils libxml2-dev
clang: git build-essential pkg-config python3 curl openjdk-11-jdk ninja-build pkg-config libncurses-dev libxml2-utils libxml2-dev
gcc: git build-essential pkg-config python3 curl openjdk-11-jdk pkg-config libncurses-dev libxml2-utils libxml2-dev
clang: git build-essential pkg-config python3 curl openjdk-11-jdk pkg-config libncurses-dev libxml2-utils libxml2-dev
msvc: ''
extra-values: |
llvm-hash: e1065370aaacb1b1cb48e77d37d376bf024f4a39
Expand All @@ -68,6 +72,8 @@ jobs:
llvm-archive-filename: {{ llvm-archive-basename }}.{{ llvm-archive-extension }}
libcxx-runtimes: libcxx;libcxxabi{{#if (ine os 'windows') }};libunwind{{/if}}
libcxx-targets: cxx {{#if (ine os 'windows') }}cxxabi unwind{{/if}} install-cxx {{#if (ine os 'windows') }}install-cxxabi install-unwind{{/if}}
libcxx-cxxflags: {{#if (ieq os 'windows') }}-D__ORDER_LITTLE_ENDIAN__=1234 -D__ORDER_BIG_ENDIAN__=4321 -D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__{{/if}}
libcxx-cmake-args: -D LLVM_ENABLE_RUNTIMES="{{ libcxx-runtimes }}" {{#if (ieq os 'windows') }}-D LIBCXXABI_USE_LLVM_UNWINDER=OFF -D LIBCXXABI_ENABLE_SHARED=OFF -D LIBCXXABI_ENABLE_STATIC=ON -D LIBCXX_ENABLE_SHARED=OFF -D LIBCXX_NO_VCRUNTIME=ON{{/if}} {{#if (ieq os 'macos') }}-D CMAKE_OSX_ARCHITECTURES=""{{/if}}
mrdocs-ccflags: {{ ccflags }} {{#if (eq compiler 'gcc') }}-static{{/if}} {{#if asan }}-static-libasan{{/if}} {{#if tsan }}-static-libtsan{{/if}}
mrdocs-cxxflags: {{ cxxflags }} {{#if (eq compiler 'gcc') }}-static{{/if}} {{#if asan }}-static-libasan{{/if}} {{#if tsan }}-static-libtsan{{/if}}
mrdocs-package-generators: {{#if (ieq os 'windows') }}7Z ZIP WIX{{else}}TGZ TXZ{{/if}}
Expand Down Expand Up @@ -131,8 +137,7 @@ jobs:
trace-commands: 'true'

- name: Setup Ninja
uses: seanmiddleditch/gha-setup-ninja@v4
if: ${{ runner.os == 'Windows' }}
uses: seanmiddleditch/gha-setup-ninja@v5

- name: Setup C++
uses: alandefreitas/cpp-actions/setup-cpp@v1.8.7
Expand All @@ -141,6 +146,15 @@ jobs:
compiler: ${{ matrix.compiler }}
version: ${{ matrix.version }}

# If apple-clang on macos, we run `clang -print-targets` to
# get the list of targets supported by the compiler.
- name: Print Clang Targets
if: matrix.compiler == 'apple-clang'
run: |
set -x
${{ steps.setup-cpp.outputs.cxx }} --print-targets
${{ steps.setup-cpp.outputs.cxx }} --print-target-triple

- name: Install System Packages
uses: alandefreitas/cpp-actions/package-install@v1.8.7
if: matrix.compiler != 'msvc'
Expand Down Expand Up @@ -323,24 +337,19 @@ jobs:
source-dir: ../third-party/llvm-project/runtimes
build-dir: ${sourceDir}/build-libcxx
build-target: ${{ matrix.libcxx-targets }}
cc: ../third-party/llvm-project/install/bin/clang
cxx: ../third-party/llvm-project/install/bin/clang++
cxxflags: ${{ runner.os == 'Windows' && '-D__ORDER_LITTLE_ENDIAN__=1234 -D__ORDER_BIG_ENDIAN__=4321 -D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__' || '' }}
# MrDocs will only use the LibC++ headers: any compiler that works in this workflow will do
cc: ${{ runner.os == 'macOS' && steps.setup-cpp.outputs.cc || '../third-party/llvm-project/install/bin/clang' }}
cxx: ${{ runner.os == 'macOS' && steps.setup-cpp.outputs.cxx || '../third-party/llvm-project/install/bin/clang++' }}
cxxflags: ${{ matrix.libcxx-cxxflags }}
generator: Ninja
extra-args: |
-D LLVM_ENABLE_RUNTIMES="${{ matrix.libcxx-runtimes }}"
${{ runner.os == 'Windows' && '-D LIBCXXABI_USE_LLVM_UNWINDER=OFF' || '' }}
${{ runner.os == 'Windows' && '-D LIBCXXABI_ENABLE_SHARED=OFF' || '' }}
${{ runner.os == 'Windows' && '-D LIBCXXABI_ENABLE_STATIC=ON' || '' }}
${{ runner.os == 'Windows' && '-D LIBCXX_ENABLE_SHARED=OFF' || '' }}
${{ runner.os == 'Windows' && '-D LIBCXX_NO_VCRUNTIME=ON' || '' }}
extra-args: ${{ matrix.libcxx-cmake-args }}
install: true
install-prefix: ${sourceDir}/../install
run-tests: false
trace-commands: true

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '20'

Expand Down Expand Up @@ -427,12 +436,12 @@ jobs:
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Setup Ninja
uses: seanmiddleditch/gha-setup-ninja@v4
uses: seanmiddleditch/gha-setup-ninja@v5
if: ${{ runner.os == 'Windows' }}

- name: Download MrDocs package
Expand All @@ -445,7 +454,8 @@ jobs:
run: |
set -x
if [[ ${{ runner.os }} != 'Windows' ]]; then
dest_dir="/usr/local"
dest_dir="$HOME/local"
mkdir -p "$dest_dir"
find packages -maxdepth 1 -name 'MrDocs-*.tar.gz' -exec tar -vxzf {} -C $dest_dir --strip-components=1 \;
else
dest_dir="$GITHUB_WORKSPACE/usr/local"
Expand Down Expand Up @@ -475,6 +485,39 @@ jobs:
modules-exclude-paths: ''
trace-commands: true

- name: Set up llvm-symbolizer
if: ${{ runner.os == 'macOS' }}
run: |
set -x

# Step 1: Check if llvm-symbolizer is installed
if ! command -v llvm-symbolizer &> /dev/null; then
echo "llvm-symbolizer is not installed. Installing via Homebrew..."
# Step 2: Install llvm if not installed
if command -v brew &> /dev/null; then
brew install llvm
else
echo "Homebrew is not installed. Please install Homebrew first: https://brew.sh/"
exit 1
fi
fi

# Step 3: Ensure llvm-symbolizer is in your PATH
llvm_bin_path=$(brew --prefix)/opt/llvm/bin
PATH="$PATH:$llvm_bin_path"
LLVM_SYMBOLIZER_PATH=$(which llvm-symbolizer)
if [ -z "$LLVM_SYMBOLIZER_PATH" ]; then
echo "llvm-symbolizer installation failed or it's not in the PATH."
exit 1
else
echo "llvm-symbolizer found at: $LLVM_SYMBOLIZER_PATH"
fi

# Step 4: Export LLVM_SYMBOLIZER_PATH environment variable
export LLVM_SYMBOLIZER_PATH="$LLVM_SYMBOLIZER_PATH"
echo -e "LLVM_SYMBOLIZER_PATH=$LLVM_SYMBOLIZER_PATH" >> $GITHUB_ENV
echo "Environment variable LLVM_SYMBOLIZER_PATH set to: $LLVM_SYMBOLIZER_PATH"

- name: Generate Landing Page
working-directory: docs/website
run: |
Expand Down
3 changes: 3 additions & 0 deletions docs/modules/ROOT/pages/install.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ export CXX="./install/bin/clang++"
export CC="./install/bin/clang"
----

These options set the C and pass:[C++] compilers to the ones previously installed by LLVM.
MrDocs only depends on the pass:[LibC++] headers, so any compiler that works for this step should be fine.

Run a command such as the following to configure LLVM:

[tabs]
Expand Down
35 changes: 31 additions & 4 deletions include/mrdocs/Dom/Object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,14 +420,29 @@ class MRDOCS_DECL
//
//------------------------------------------------

/** A lazy Object implementation.
/** Abstract lazy object interface.

This implementation is used to construct an
Object on demand.
This interface is used to define objects
that are constructed on demand.

The subclass must override the `construct`
function to return the constructed object.
It will typically also store whatever
data is necessary to construct this object.

When any of the object properties are accessed
for the first time, the object is constructed.
This can happen via any of the public functions,
such as `get`, `set`, `size`, `exists`, or `visit`.

The underlying object storage is only
initialized when the first property is
set or accessed.
set or accessed. In practice, it means
the object is never initialized if it's
not used in a template.

When the object is initialized, the

*/
class MRDOCS_DECL
LazyObjectImpl : public ObjectImpl
Expand All @@ -440,6 +455,18 @@ class MRDOCS_DECL

using impl_type = Object::impl_type;

/* Return the constructed object.

This function is invoked by all public
functions that access the object properties.

When invoked for the first time, the object
is constructed and stored in the shared
pointer.

Further invocations return a reference
to the existing value in the shared pointer.
*/
ObjectImpl& obj() const;

protected:
Expand Down
4 changes: 2 additions & 2 deletions include/mrdocs/Platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ namespace mrdocs {
# endif
#endif

#if ! defined(__x86_64__) && ! defined(_WIN64)
# error mrdox requires a 64-bit archtecture
#if ! defined(__x86_64__) && ! defined(_WIN64) && ! defined(__aarch64__)
# error mrdocs requires a 64-bit architecture
#endif

} // mrdocs
Expand Down
24 changes: 19 additions & 5 deletions src/lib/Dom/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,29 @@ LazyObjectImpl::
obj() const
{
#ifdef __cpp_lib_atomic_shared_ptr
auto impl = sp_.load();
if(impl)
std::shared_ptr<ObjectImpl> impl = sp_.load();
if (impl)
{
// Already initialized
return *impl;
impl_type expected = nullptr;
if(sp_.compare_exchange_strong(
expected, construct().impl()))
}

// Fetch the shared pointer from the factory
std::shared_ptr<ObjectImpl> expected = nullptr;
std::shared_ptr<ObjectImpl> desired = construct().impl();
MRDOCS_ASSERT(desired);
if (sp_.compare_exchange_strong(expected, std::move(desired)))
{
return *sp_.load();
}
return *expected;
#else
if (sp_)
{
return *sp_;
}
sp_ = construct().impl();
MRDOCS_ASSERT(sp_);
return *sp_;
#endif
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib/Lib/CMakeExecution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,9 @@ parseBashArgs(std::string_view str)
return args;
}

/* Pushes the CMake arguments to the `args` vector, replacing the
* default generator with Ninja if Visual Studio is the default generator.
*/
Expected<void>
pushCMakeArgs(
std::string const& cmakePath,
Expand Down
83 changes: 81 additions & 2 deletions src/lib/Lib/MrDocsCompilationDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <llvm/Option/ArgList.h>
#include <llvm/Option/OptTable.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/Program.h>
#include <llvm/TargetParser/Host.h>
#include <ranges>

namespace clang {
Expand Down Expand Up @@ -243,8 +245,8 @@ static
std::vector<std::string>
adjustCommandLine(
llvm::StringRef workingDir,
const std::vector<std::string>& cmdline,
const std::vector<std::string>& additional_defines,
std::vector<std::string> const& cmdline,
std::vector<std::string> const& additional_defines,
std::unordered_map<std::string, std::vector<std::string>> const& implicitIncludeDirectories,
std::vector<std::string> const& stdlibIncludes,
std::vector<std::string> const& systemIncludes,
Expand Down Expand Up @@ -292,6 +294,83 @@ adjustCommandLine(
new_cmdline.emplace_back(is_clang_cl ? "/w" : "-w");
new_cmdline.emplace_back("-fsyntax-only");

// ------------------------------------------------------
// Target architecture
// ------------------------------------------------------
constexpr auto is_target_option = [](std::string_view opt) {
return opt == "-target" || opt == "--target";
};
if (std::ranges::find_if(cmdline, is_target_option) == cmdline.end())
{
auto getCommandCompilerTarget = [&]() -> std::string {
ScopedTempFile const outputPath("compiler-triple", "txt");
if (!outputPath) {
return {};
}
std::vector<llvm::StringRef> args = {
progName, "--print-target-triple"
};
std::optional<llvm::StringRef> const redirects[] = {
llvm::StringRef(),
outputPath.path(),
llvm::StringRef()
};
int const result = llvm::sys::ExecuteAndWait(
progName, args, std::nullopt, redirects);
if (result != 0)
{
return {};
}

auto const bufferOrError = llvm::MemoryBuffer::getFile(
outputPath.path());
if (!bufferOrError) {
return {};
}
return bufferOrError.get()->getBuffer().trim().str();
};

[&]() {
std::string target = llvm::sys::getDefaultTargetTriple();

if (target.empty())
{
target = llvm::sys::getProcessTriple();
}

if (target.empty())
{
target = getCommandCompilerTarget();
}

#if defined(__APPLE__)
if (target.empty())
{
target = "arm64-apple-darwin24.0.0";
}
#else
if (target.empty())
{
return;
}
#endif

new_cmdline.emplace_back("-target");
new_cmdline.emplace_back(target);
}();
}

// ------------------------------------------------------
// Language standard
// ------------------------------------------------------
constexpr auto is_std_option = [](std::string_view opt) {
return opt.starts_with("-std=") || opt.starts_with("--std=") || opt.starts_with("/std:");
};
if (std::ranges::find_if(cmdline, is_std_option) == cmdline.end())
{
new_cmdline.emplace_back("-std=c++23");
}

// ------------------------------------------------------
// Add additional defines
// ------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Support/Error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ call_impl(
e->location().line());
}
os << fmt::format(
" Reported From: `{}` at line {}",
" Reported From: `{}` at line {}\n",
::SourceFileNames::getFileName(loc->file_name()),
loc->line());
// VFALCO attach a stack trace for Level::fatal
Expand Down
Loading