Add standalone cxx-common alternative

This commit is contained in:
Duncan Ogilvie
2025-10-26 14:33:10 +01:00
committed by Kyle Elliott
parent b6fc70f0f4
commit 8e40ccc60e
8 changed files with 380 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
build*/
install*/
+2
View File
@@ -0,0 +1,2 @@
build*/
install*/
+50
View File
@@ -0,0 +1,50 @@
# https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-1.html
cmake_minimum_required(VERSION 3.21)
project(cxx-common)
option(USE_EXTERNAL_LLVM "Do not compile LLVM as part of the superbuild, use an external one instead" OFF)
option(USE_SANITIZERS "Use ASan and UBSan" OFF)
if(USE_EXTERNAL_LLVM)
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin" AND NOT CMAKE_PREFIX_PATH)
execute_process(
COMMAND brew --prefix llvm
RESULT_VARIABLE BREW_LLVM
OUTPUT_VARIABLE BREW_LLVM_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(BREW_LLVM EQUAL 0 AND EXISTS "${BREW_LLVM_PREFIX}")
set(CMAKE_PREFIX_PATH "${BREW_LLVM_PREFIX}")
message(STATUS "Found LLVM keg installed by Homebrew at ${BREW_LLVM_PREFIX}")
else()
message(FATAL_ERROR "LLVM not found, to install: brew install llvm")
endif()
endif()
find_package(LLVM CONFIG REQUIRED)
message(STATUS "LLVM ${LLVM_PACKAGE_VERSION}: ${LLVM_DIR}")
endif()
if(USE_SANITIZERS)
list(APPEND CMAKE_C_FLAGS "-fsanitize=address,undefined")
list(APPEND CMAKE_CXX_FLAGS "-fsanitize=address,undefined")
endif()
include(superbuild.cmake)
simple_git(https://github.com/gflags/gflags 52e94563eba1968783864942fedf6e87e3c611f4
)
simple_git(https://github.com/google/glog v0.7.1
"-DGFLAGS_USE_TARGET_NAMESPACE:STRING=ON"
"-DBUILD_TESTING:STRING=OFF"
)
simple_git(https://github.com/google/googletest v1.17.0
"-Dgtest_force_shared_crt:STRING=ON"
"-DGFLAGS_USE_TARGET_NAMESPACE:STRING=ON"
)
include(xed.cmake)
if(NOT USE_EXTERNAL_LLVM)
include(llvm.cmake)
endif()
+12
View File
@@ -0,0 +1,12 @@
# dependencies
Alternative to `cxx-common` based on [LLVMParty/packages](https://github.com/LLVMParty/packages) (superbuild pattern).
## Building
```sh
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
```
This will create a [CMake prefix](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure), which you pass to your project with `-DCMAKE_PREFIX_PATH=/path/to/dependencies/install`. See [presentation.md](https://github.com/LLVMParty/packages/blob/main/presentation.md) and [dependencies.md](https://github.com/LLVMParty/packages/blob/main/dependencies.md) for more information.
+25
View File
@@ -0,0 +1,25 @@
# /Users/admin/Projects/cxx-common/ports/xed/XEDConfig.cmake
if(XED_FOUND)
return()
endif()
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
find_library(XED_LIBRARY xed PATHS "${PACKAGE_PREFIX_DIR}/lib" NO_CACHE REQUIRED NO_DEFAULT_PATH)
add_library(XED::XED STATIC IMPORTED)
set_target_properties(XED::XED PROPERTIES
IMPORTED_CONFIGURATIONS "NOCONFIG"
IMPORTED_LOCATION_NOCONFIG "${XED_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/include"
)
find_library(ILD_LIBRARY xed-ild PATHS "${PACKAGE_PREFIX_DIR}/lib" NO_CACHE REQUIRED NO_DEFAULT_PATH)
add_library(XED::ILD STATIC IMPORTED)
set_target_properties(XED::ILD PROPERTIES
IMPORTED_CONFIGURATIONS "NOCONFIG"
IMPORTED_LOCATION_NOCONFIG "${XED_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${PACKAGE_PREFIX_DIR}/include"
)
set(XED_FOUND ON)
+40
View File
@@ -0,0 +1,40 @@
option(LLVM_ENABLE_ASSERTIONS "Enable assertions in LLVM" ON)
# Default values for LLVM_URL and LLVM_SHA256. This is required because "-DLLVM_URL=" would be an empty URL
if("${LLVM_URL}" STREQUAL "")
set(LLVM_URL "https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/llvm-project-17.0.6.src.tar.xz")
endif()
if("${LLVM_SHA256}" STREQUAL "")
set(LLVM_SHA256 "58a8818c60e6627064f312dbf46c02d9949956558340938b71cf731ad8bc0813")
endif()
set(LLVM_ARGS
"-DLLVM_ENABLE_PROJECTS:STRING=lld;clang;clang-tools-extra"
"-DLLVM_ENABLE_ASSERTIONS:STRING=${LLVM_ENABLE_ASSERTIONS}"
"-DLLVM_ENABLE_DUMP:STRING=${LLVM_ENABLE_ASSERTIONS}"
"-DLLVM_ENABLE_RTTI:STRING=ON"
"-DLLVM_ENABLE_LIBEDIT:STRING=OFF"
"-DLLVM_PARALLEL_LINK_JOBS:STRING=1"
"-DLLVM_ENABLE_DIA_SDK:STRING=OFF"
# This is meant for LLVM development, we use the DYLIB option instead
"-DBUILD_SHARED_LIBS:STRING=OFF"
"-DLLVM_LINK_LLVM_DYLIB:STRING=${BUILD_SHARED_LIBS}"
)
if(USE_SANITIZERS)
list(APPEND LLVM_ARGS "-DLLVM_USE_SANITIZER:STRING=Address;Undefined")
endif()
ExternalProject_Add(llvm
URL
${LLVM_URL}
URL_HASH
"SHA256=${LLVM_SHA256}"
CMAKE_CACHE_ARGS
${CMAKE_ARGS}
${LLVM_ARGS}
CMAKE_GENERATOR
"Ninja"
SOURCE_SUBDIR
"llvm"
)
+161
View File
@@ -0,0 +1,161 @@
include_guard()
option(BUILD_SHARED_LIBS "Build using shared libraries" OFF)
# Bail out early for multi-config generators
if(CMAKE_CONFIGURATION_TYPES)
message(FATAL_ERROR "Multi-config generators are not supported. Use Make/NMake/Ninja instead")
endif()
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
endif()
# Default to a Release config
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "")
if(CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
endif()
message(STATUS "Configuration: ${CMAKE_BUILD_TYPE}")
# Default to build/install (setting this variable is not recommended and might cause conflicts)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/../install" CACHE PATH "Install prefix" FORCE)
endif()
message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
# Save the host platform in the install prefix
make_directory(${CMAKE_INSTALL_PREFIX})
file(TOUCH ${CMAKE_INSTALL_PREFIX}/${CMAKE_SYSTEM}.build)
# Git is necessary for submodules
find_package(Git REQUIRED)
message(STATUS "Git: ${GIT_EXECUTABLE}")
# Ninja is necessary for building the dependencies
find_program(ninja_EXECUTABLE ninja NO_CACHE NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_INSTALL_PREFIX NO_CMAKE_FIND_ROOT_PATH)
if(ninja_EXECUTABLE STREQUAL "ninja_EXECUTABLE-NOTFOUND")
message(FATAL_ERROR "Could not find 'ninja' in the PATH")
endif()
message(STATUS "Ninja: ${ninja_EXECUTABLE}")
# Documentation: https://cmake.org/cmake/help/latest/module/ExternalProject.html
include(ExternalProject)
# Hook for ExternalProject_Add to make sure projects build in order
function(ExternalProject_Add name)
# The DEPENDS argument is fully implicit
cmake_parse_arguments(HOOK "" "" DEPENDS ${ARGN})
if(HOOK_DEPENDS)
message(FATAL_ERROR "Explicit DEPENDS (${HOOK_DEPENDS}) not supported")
endif()
# Update the LAST_EXTERNAL_PROJECT property
get_property(LAST_EXTERNAL_PROJECT GLOBAL PROPERTY LAST_EXTERNAL_PROJECT)
set_property(GLOBAL PROPERTY LAST_EXTERNAL_PROJECT ${name})
# Pass the previous project as a dependency to this call
if(LAST_EXTERNAL_PROJECT)
set(HOOK_ARGS DEPENDS "${LAST_EXTERNAL_PROJECT}")
message(STATUS "ExternalProject: ${name} depends on ${LAST_EXTERNAL_PROJECT}")
else()
message(STATUS "ExternalProject: ${name}")
endif()
_ExternalProject_Add(${name} ${ARGN} ${HOOK_ARGS}
# Reference: https://www.scivision.dev/cmake-external-project-ninja-verbose/
USES_TERMINAL_DOWNLOAD ON
USES_TERMINAL_UPDATE ON
USES_TERMINAL_PATCH ON
USES_TERMINAL_CONFIGURE ON
USES_TERMINAL_BUILD ON
USES_TERMINAL_INSTALL ON
USES_TERMINAL_TEST ON
DOWNLOAD_EXTRACT_TIMESTAMP ON
)
endfunction()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
# Suppress warnings for clang-cl builds, some of these cause compilation errors.
list(APPEND ADDITIONAL_FLAGS "-w")
elseif(UNIX AND NOT APPLE)
# To compile shared libraries, everything needs to be compiled as position independent code when using clang on linux
list(APPEND ADDITIONAL_FLAGS "-fPIC")
endif()
endif()
# Convert a CMake list to a space-separated list
list(JOIN ADDITIONAL_FLAGS " " ADDITIONAL_FLAGS)
# Default cache variables for all projects
list(APPEND CMAKE_ARGS
"-DCMAKE_PREFIX_PATH:FILEPATH=${CMAKE_INSTALL_PREFIX};${CMAKE_PREFIX_PATH}"
"-DCMAKE_INSTALL_PREFIX:FILEPATH=${CMAKE_INSTALL_PREFIX}"
"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
"-DBUILD_SHARED_LIBS:STRING=${BUILD_SHARED_LIBS}"
"-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}"
"-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}"
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${ADDITIONAL_FLAGS}"
"-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${ADDITIONAL_FLAGS}"
)
if(CMAKE_C_COMPILER_LAUNCHER)
list(APPEND CMAKE_ARGS "-DCMAKE_C_COMPILER_LAUNCHER:STRING=${CMAKE_C_COMPILER_LAUNCHER}")
endif()
if(CMAKE_CXX_COMPILER_LAUNCHER)
list(APPEND CMAKE_ARGS "-DCMAKE_CXX_COMPILER_LAUNCHER:STRING=${CMAKE_CXX_COMPILER_LAUNCHER}")
endif()
message(STATUS "Compiling all dependencies with the following CMake arguments:")
foreach(CMAKE_ARG ${CMAKE_ARGS})
message("\t${CMAKE_ARG}")
endforeach()
function(simple_git repo tag)
get_filename_component(name "${repo}" NAME_WE)
ExternalProject_Add(${name}
GIT_REPOSITORY
"${repo}"
GIT_TAG
"${tag}"
GIT_PROGRESS
ON
CMAKE_CACHE_ARGS
${CMAKE_ARGS}
${ARGN}
CMAKE_GENERATOR
"Ninja"
)
endfunction()
function(simple_submodule folder)
set(folder_path "${CMAKE_CURRENT_SOURCE_DIR}/${folder}")
if(NOT EXISTS "${folder_path}" OR NOT EXISTS "${folder_path}/CMakeLists.txt")
message(STATUS "Submodule '${folder}' not initialized, running git...")
execute_process(
COMMAND "${GIT_EXECUTABLE}" rev-parse --show-toplevel
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE git_root
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND "${GIT_EXECUTABLE}" submodule update --init
WORKING_DIRECTORY "${git_root}"
COMMAND_ERROR_IS_FATAL ANY
)
endif()
ExternalProject_Add(${folder}
SOURCE_DIR
"${folder_path}"
CMAKE_CACHE_ARGS
${CMAKE_ARGS}
${ARGN}
CMAKE_GENERATOR
"Ninja"
# Always trigger the build step (necessary because there is no download step)
BUILD_ALWAYS
ON
)
endfunction()
+88
View File
@@ -0,0 +1,88 @@
find_package(Python3 COMPONENTS Interpreter REQUIRED)
message(STATUS "Python3: ${Python3_EXECUTABLE}")
# Reference: https://github.com/lifting-bits/cxx-common/blob/e0063b2f5986582ed8dcab0c2863abf0893b3082/ports/xed/portfile.cmake
# TODO: pass compiler flags
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND MSVC)
set(compiler ms) #msvc or clang-cl
elseif(CMAKE_CXX_COMPILER_ID MATCHES "^(Apple)?Clang$")
set(compiler clang)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(compiler gnu)
else()
message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
endif()
set(MFILE_ARGS
"install"
"--install-dir=install"
"--cc=${CMAKE_C_COMPILER}"
"--cxx=${CMAKE_CXX_COMPILER}"
"--compiler=${compiler}"
)
if(CMAKE_OSX_SYSROOT)
list(APPEND MFILE_ARGS "--extra-ccflags=-isysroot ${CMAKE_OSX_SYSROOT}")
list(APPEND MFILE_ARGS "--extra-cxxflags=-isysroot ${CMAKE_OSX_SYSROOT}")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
list(APPEND MFILE_ARGS "--extra-ccflags=${ADDITIONAL_FLAGS}")
list(APPEND MFILE_ARGS "--extra-cxxflags=${ADDITIONAL_FLAGS}")
endif()
if(USE_SANITIZERS)
list(APPEND MFILE_ARGS "--extra-ccflags=-fsanitize=address,undefined")
list(APPEND MFILE_ARGS "--extra-cxxflags=-fsanitize=address,undefined")
endif()
if(BUILD_SHARED_LIBS)
list(APPEND MFILE_ARGS "--shared")
else()
list(APPEND MFILE_ARGS "--static")
endif()
if(CMAKE_AR)
list(APPEND MFILE_ARGS "--ar=${CMAKE_AR}")
endif()
ExternalProject_Add(mbuild
GIT_REPOSITORY
"https://github.com/intelxed/mbuild"
GIT_TAG
"v2022.04.17"
GIT_PROGRESS
ON
CONFIGURE_COMMAND
"${CMAKE_COMMAND}" -E true
BUILD_COMMAND
"${CMAKE_COMMAND}" -E true
INSTALL_COMMAND
"${CMAKE_COMMAND}" -E true
PREFIX
xed-prefix
)
ExternalProject_Add(xed
GIT_REPOSITORY
"https://github.com/intelxed/xed"
GIT_TAG
"v2022.04.17"
GIT_PROGRESS
ON
CMAKE_CACHE_ARGS
${CMAKE_ARGS}
CONFIGURE_COMMAND
"${CMAKE_COMMAND}" -E true
BUILD_COMMAND
"${Python3_EXECUTABLE}" "<SOURCE_DIR>/mfile.py" ${MFILE_ARGS}
INSTALL_COMMAND
"${CMAKE_COMMAND}" -E copy_directory <BINARY_DIR>/install "${CMAKE_INSTALL_PREFIX}"
PREFIX
xed-prefix
)
# TODO: generate XEDVersion.cmake as well file
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/XEDConfig.cmake.in" "${CMAKE_INSTALL_PREFIX}/lib/cmake/XED/XEDConfig.cmake" @ONLY)