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
105 changes: 40 additions & 65 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,73 +1,48 @@
name: CI
on: [push, pull_request]

jobs:
# Here we're keeping on arbitrary LLVM version fixed and varying GCC.
linux-gcc:
strategy:
fail-fast: false
matrix:
image:
# List: https://github.com/conan-io/conan-docker-tools
- gcc10
- gcc9
- gcc8
- gcc7
- gcc6

runs-on: ubuntu-latest
container:
image: conanio/${{matrix.image}}
options: --user root

steps:
- uses: actions/checkout@v2
- name: Create Build Environment
run: cmake -E make_directory build
- name: Install libclang
run: apt-get -qq update && apt-get install -y llvm clang libclang-dev
- name: Install ninja
run: type ninja || apt-get install -y ninja-build
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

- name: Configure
working-directory: build/
run: cmake -GNinja $GITHUB_WORKSPACE
- name: Build
working-directory: build/
run: cmake --build .
- name: Test
working-directory: build/
run: ctest --output-on-failure

# Here we're varying the LLVM version and using its clang for compiling as well.
linux-clang:
jobs:
test:
runs-on: ${{ matrix.on }}
strategy:
fail-fast: false
matrix:
version: [7, 8, 9, 10]

runs-on: ubuntu-latest
container:
# Just one of the newer images.
image: conanio/gcc10
options: --user root
include:
- { environment: "llvm-15", on: "ubuntu-24.04" }
- { environment: "llvm-16", on: "ubuntu-24.04" }
- { environment: "llvm-17", on: "ubuntu-24.04" }
- { environment: "llvm-18", on: "ubuntu-24.04" }
- { environment: "llvm-19", on: "ubuntu-24.04" }
- { environment: "llvm-20", on: "ubuntu-24.04" }
- { environment: "llvm-21", on: "ubuntu-24.04" }
- { environment: "llvm-22", on: "ubuntu-24.04" }
# The Xcode 16.x SDK is not compatible with such an old clang
# - { environment: "llvm-15", on: "macos-15" }
# - { environment: "llvm-16", on: "macos-15" }
# - { environment: "llvm-17", on: "macos-15" }
# - { environment: "llvm-18", on: "macos-15" }
- { environment: "llvm-19", on: "macos-15" }
# conda cannot solve for clangdev=20,21,22 on Silicon
# - { environment: "llvm-20", on: "macos-15" }
# - { environment: "llvm-21", on: "macos-15" }
# - { environment: "llvm-22", on: "macos-15" }
# The Xcode 16.x SDK is not compatible with such an old clang
# - { environment: "llvm-15", on: "macos-15-intel" }
# - { environment: "llvm-16", on: "macos-15-intel" }
# - { environment: "llvm-17", on: "macos-15-intel" }
# - { environment: "llvm-18", on: "macos-15-intel" }
- { environment: "llvm-19", on: "macos-15-intel" }
- { environment: "llvm-20", on: "macos-15-intel" }
- { environment: "llvm-21", on: "macos-15-intel" }
- { environment: "llvm-22", on: "macos-15-intel" }

steps:
- uses: actions/checkout@v2
- name: Create Build Environment
run: cmake -E make_directory build
- name: Install libclang
run: apt-get -qq update && apt-get install -y llvm-${{matrix.version}} clang-${{matrix.version}} libclang-${{matrix.version}}-dev
- name: Install ninja
run: type ninja || apt-get install -y ninja-build

- name: Configure
working-directory: build/
run: cmake -GNinja $GITHUB_WORKSPACE -DCMAKE_CXX_COMPILER=clang++-${{matrix.version}}
- name: Build
working-directory: build/
run: cmake --build .
- name: Test
working-directory: build/
run: ctest --output-on-failure

- uses: actions/checkout@v5
with: { submodules: recursive }
- uses: prefix-dev/setup-pixi@v0.9.4
with: { pixi-version: v0.68.0 }
- name: run tests
run: pixi run -e ${{ matrix.environment }} test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build
/Testing
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: MIT
# found in the top-level directory of this distribution.

cmake_minimum_required(VERSION 3.11)
cmake_minimum_required(VERSION 4.0)
project(cppast VERSION 0.1.0)

if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
Expand Down
14 changes: 4 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,17 @@ TODO, refer to documentation comments in header file.

### Installation

The library can be used as CMake subdirectory, download it and call `add_subdirectory(path/to/cppast)`, then link to the `cppast` target and enable C++11 or higher.
For development, we recommend to use [pixi](https://pixi.sh). Run `pixi run build` to compile the package, `pixi run test` to run its test suite, `pixi run cppast` to run the cppast tool.

The parser needs `libclang` and the `clang++` binary, at least version 4.0.0.
The `clang++` binary will be found in `PATH` and in the same directory as the program that is being executed.
The library can also be used as CMake subdirectory, download it and call `add_subdirectory(path/to/cppast)`, then link to the `cppast` target and enable C++11 or higher.

*Note: The project will drop support for older LLVM versions very soon; this minimizes the workaround code when the `libclang` API catches up.*
The parser needs `libclang` and the `clang++` binary, at least version 15.
The `clang++` binary will be found in `PATH` and in the same directory as the program that is being executed.

The CMake code requires `llvm-config`, you may need to install `llvm` and not just `clang` to get it (e.g. on ArchLinux).
If `llvm-config` is in your path and the version is compatible, it should just work out of the box.
Else you need to set the CMake variable `LLVM_CONFIG_BINARY` to the proper path.

If you don't have a proper clang version installed, it can also be downloaded.
For that you need to set `LLVM_DOWNLOAD_OS_NAME`.
This is the name of the operating system used on the [LLVM pre-built binary archive](http://releases.llvm.org/download.html#4.0.0), e.g. `x86_64-linux-gnu-ubuntu-16.10` for Ubuntu 16.10.

You can also set `LLVM_DOWNLOAD_URL` to a custom url, to download a specific version or from a mirror.

If you don't have `llvm-config`, you need to pass the locations explictly.
For that set the option `LLVM_VERSION_EXPLICIT` to the version you're using,
`LIBCLANG_LIBRARY` to the location of the libclang library file,
Expand Down
77 changes: 9 additions & 68 deletions external/external.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ include(FetchContent)
find_package(type_safe QUIET)
if(NOT type_safe_FOUND)
message(STATUS "Fetching type_safe")
FetchContent_Declare(type_safe GIT_REPOSITORY https://github.com/foonathan/type_safe GIT_TAG origin/main)
FetchContent_Declare(type_safe GIT_REPOSITORY https://github.com/foonathan/type_safe GIT_TAG 292e8c127037e33d92f8f52dab0f1184993942d0) # main as of 2026-05-20
FetchContent_MakeAvailable(type_safe)
endif()

Expand All @@ -31,7 +31,7 @@ if(build_tool)
set(CXXOPTS_BUILD_TESTS OFF CACHE BOOL "")

message(STATUS "Fetching cxxopts")
FetchContent_Declare(cxxopts URL https://github.com/jarro2783/cxxopts/archive/v2.2.1.zip)
FetchContent_Declare(cxxopts GIT_REPOSITORY https://github.com/jarro2783/cxxopts GIT_TAG a3a21b31ef2894b5a802f041f40d51059469a259) # master as of 2026-05-20
FetchContent_MakeAvailable(cxxopts)
endif()

Expand All @@ -50,38 +50,6 @@ function(name_without_extension FILENAME NAME)
set(${NAME} "${name_we}" PARENT_SCOPE)
endfunction()

# downloads and extracts LLVM using the given URL, filename, and extension
# sets: LLVM_DOWNLOAD_DIR
function(_cppast_download_llvm url)
get_filename_component(file "${url}" NAME)
name_without_extension(${file} folder)

if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${folder})
message(STATUS "Downloading LLVM from ${url}")
file(DOWNLOAD ${url} ${CMAKE_CURRENT_BINARY_DIR}/${file}
STATUS status
LOG log)

list(GET status 0 status_code)
list(GET status 1 status_string)
if(NOT status_code EQUAL 0)
message(FATAL_ERROR "error downloading llvm: ${status_string}" "${log}")
endif()

execute_process(COMMAND ${CMAKE_COMMAND} -E tar xJf ${file}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()

set(LLVM_DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${folder} PARENT_SCOPE)
endfunction()

# downloads and extracts LLVM using the given version and OS name
# sets: LLVM_DOWNLOAD_DIR
function(_cppast_download_llvm_from_llvm_releases version os)
_cppast_download_llvm("http://releases.llvm.org/${version}/clang+llvm-${version}-${os}.tar.xz")
set(LLVM_DOWNLOAD_DIR ${LLVM_DOWNLOAD_DIR} PARENT_SCOPE)
endfunction()

# determines the llvm version from a config binary
macro(_cppast_llvm_version output_name llvm_binary)
execute_process(COMMAND ${llvm_binary} --version
Expand All @@ -94,34 +62,16 @@ endmacro()
# finds the llvm-config binary
# sets: LLVM_CONFIG_BINARY
function(_cppast_find_llvm_config)
unset(LLVM_CONFIG_BINARY CACHE)
if(LLVM_DOWNLOAD_DIR)
find_program(LLVM_CONFIG_BINARY "llvm-config" "${LLVM_DOWNLOAD_DIR}/bin" NO_DEFAULT_PATH)
else()
find_program(llvm_config_binary_no_suffix llvm-config)
find_program(llvm_config_binary_suffix NAMES llvm-config-10 llvm-config-9 llvm-config-8 llvm-config-7 llvm-config-6.0 llvm-config-5.0 llvm-config-4.0)
if(NOT LLVM_CONFIG_BINARY)

find_program(LLVM_CONFIG_BINARY llvm-config)

if(NOT llvm_config_binary_no_suffix)
set(LLVM_CONFIG_BINARY ${llvm_config_binary_suffix} CACHE INTERNAL "")
elseif(NOT llvm_config_binary_suffix)
set(LLVM_CONFIG_BINARY ${llvm_config_binary_no_suffix} CACHE INTERNAL "")
if(NOT LLVM_CONFIG_BINARY)
message(FATAL_ERROR "Unable to find llvm-config binary, please set option LLVM_CONFIG_BINARY yourself")
else()
# pick latest version of the two
_cppast_llvm_version(suffix_version ${llvm_config_binary_suffix})
_cppast_llvm_version(no_suffix_version ${llvm_config_binary_no_suffix})
if(suffix_version VERSION_GREATER no_suffix_version)
set(LLVM_CONFIG_BINARY ${llvm_config_binary_suffix} CACHE INTERNAL "")
else()
set(LLVM_CONFIG_BINARY ${llvm_config_binary_no_suffix} CACHE INTERNAL "")
endif()
message(STATUS "Found llvm-config at ${LLVM_CONFIG_BINARY}")
endif()
endif()

if(NOT LLVM_CONFIG_BINARY)
message(FATAL_ERROR "Unable to find llvm-config binary, please set option LLVM_CONFIG_BINARY yourself")
else()
message(STATUS "Found llvm-config at ${LLVM_CONFIG_BINARY}")
endif()
endfunction()

# find libclang using the config tool
Expand Down Expand Up @@ -202,11 +152,7 @@ function(_cppast_find_libclang config_tool min_version force)
endif()
endfunction()

set(llvm_min_version 4.0.0)

if(NOT DEFINED LLVM_PREFERRED_VERSION)
set(LLVM_PREFERRED_VERSION 4.0.0 CACHE STRING "the preferred LLVM version")
endif()
set(llvm_min_version 15.0.0)

if(DEFINED LLVM_VERSION_EXPLICIT)
if(LLVM_VERSION_EXPLICIT VERSION_LESS llvm_min_version)
Expand All @@ -215,11 +161,6 @@ if(DEFINED LLVM_VERSION_EXPLICIT)
set(LLVM_VERSION ${LLVM_VERSION_EXPLICIT} CACHE INTERNAL "")
message(STATUS "Using manually specified LLVM version ${LLVM_VERSION}")
elseif(NOT LLVM_CONFIG_BINARY)
if(DEFINED LLVM_DOWNLOAD_OS_NAME)
_cppast_download_llvm_from_llvm_releases(${LLVM_PREFERRED_VERSION} ${LLVM_DOWNLOAD_OS_NAME})
elseif(DEFINED LLVM_DOWNLOAD_URL)
_cppast_download_llvm(${LLVM_DOWNLOAD_URL})
endif()
_cppast_find_llvm_config()
_cppast_find_libclang(${LLVM_CONFIG_BINARY} ${llvm_min_version} 1) # override here
else()
Expand Down
2 changes: 1 addition & 1 deletion external/tpl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 4.0)

project(tiny-process-library)

Expand Down
10 changes: 5 additions & 5 deletions include/cppast/compile_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ class compile_config
return do_use_c();
}

void add_flag(std::string flag)
{
flags_.push_back(std::move(flag));
}

protected:
compile_config(std::vector<std::string> def_flags) : flags_(std::move(def_flags)) {}

Expand All @@ -176,11 +181,6 @@ class compile_config

~compile_config() noexcept = default;

void add_flag(std::string flag)
{
flags_.push_back(std::move(flag));
}

const std::vector<std::string>& get_flags() const noexcept
{
return flags_;
Expand Down
2 changes: 1 addition & 1 deletion include/cppast/cpp_entity_index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct cpp_entity_id : type_safe::strong_typedef<cpp_entity_id, detail::hash_typ
inline namespace literals
{
/// \returns A new [cppast::cpp_entity_id]() created from the given string.
inline cpp_entity_id operator"" _id(const char* str, std::size_t)
inline cpp_entity_id operator""_id(const char* str, std::size_t)
{
return cpp_entity_id(str);
}
Expand Down
Loading
Loading