Skip to content

Conversation

Montana
Copy link

@Montana Montana commented Aug 12, 2025

Historically, Abseil does not support shared libraries on Windows, and building both static and shared variants in a single workflow can be tricky. This change introduces a simplified CMake Superbuild that uses two ExternalProject calls to build static and shared libraries separately, while allowing them to coexist under the same install prefix.

The Superbuild is wrapped in a Bash script and uses Ninja Multi-Config when available to improve build speed and parallelism. This approach ensures both variants are installed in one execution without duplicating source checkout steps.

For example, this is the Bash driver to run Superbuild:

#!/usr/bin/env bash
set -Eeuo pipefail

: "${SOURCE_DIR:?SOURCE_DIR must be set}"
source "${SOURCE_DIR}/functions.sh"

THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
prepare "${THIS_DIR}"
cd "${THIS_DIR}"

ABSEIL_CPP_GITHUB_URL="${ABSEIL_CPP_GITHUB_URL:-https://github.com/abseil/abseil-cpp.git}"
ABSEIL_CPP_SOURCE_DIR="abseil-cpp-${PACKAGE_VERSION:?PACKAGE_VERSION not set}"

if [[ ! -d "${ABSEIL_CPP_SOURCE_DIR}" ]]; then
  git clone --depth 1 --branch "${PACKAGE_VERSION}" "${ABSEIL_CPP_GITHUB_URL}" "${ABSEIL_CPP_SOURCE_DIR}"
fi

rm -rf superbuild
mkdir superbuild
cp superbuild/CMakeLists.txt superbuild/CMakeLists.txt

pushd superbuild >/dev/null
cmake -DABSEIL_CPP_SOURCE_DIR="${ABSEIL_CPP_SOURCE_DIR}" .
cmake --build . --target install_all -j"${BUILD_THREADS:-4}"
popd >/dev/null

I've also added a superbuild/CMakeLists.txt that defines absl_static and absl_shared using ExternalProject_Add, with separate build directories for each variant to avoid conflicts. A single install_all target is introduced to install both variants in one step, and the configuration automatically skips building the shared variant on WIN32 platforms for compatibility:

cmake_minimum_required(VERSION 3.20)
project(absl_superbuild)
include(ExternalProject)

if(NOT DEFINED ENV{LOCAL_INSTALL})
  message(FATAL_ERROR "LOCAL_INSTALL env not set")
endif()
if(NOT DEFINED ABSEIL_CPP_SOURCE_DIR)
  message(FATAL_ERROR "ABSEIL_CPP_SOURCE_DIR cache var not set")
endif()

set(PREFIX $ENV{LOCAL_INSTALL})
set(SRC_DIR "${CMAKE_SOURCE_DIR}/../${ABSEIL_CPP_SOURCE_DIR}")

set(COMMON_ARGS
  -DCMAKE_BUILD_TYPE=Release
  -DCMAKE_INSTALL_PREFIX=${PREFIX}
  -DABSL_ENABLE_INSTALL=ON
  -DABSL_BUILD_TESTING=OFF
  -DCMAKE_POSITION_INDEPENDENT_CODE=ON
  -DABSL_PROPAGATE_CXX_STD=ON
  -DCMAKE_INSTALL_RPATH=${PREFIX}/lib
  -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON
)

ExternalProject_Add(absl_static
  SOURCE_DIR "${SRC_DIR}"
  BINARY_DIR "${CMAKE_BINARY_DIR}/absl_static"
  DOWNLOAD_COMMAND ""
  CMAKE_ARGS ${COMMON_ARGS} -DBUILD_SHARED_LIBS=OFF
  BUILD_COMMAND ${CMAKE_COMMAND} --build . -j $ENV{BUILD_THREADS}
  INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install -j $ENV{BUILD_THREADS}
)

if(NOT WIN32)
  ExternalProject_Add(absl_shared
    SOURCE_DIR "${SRC_DIR}"
    BINARY_DIR "${CMAKE_BINARY_DIR}/absl_shared"
    DOWNLOAD_COMMAND ""
    CMAKE_ARGS ${COMMON_ARGS} -DBUILD_SHARED_LIBS=ON
    BUILD_COMMAND ${CMAKE_COMMAND} --build . -j $ENV{BUILD_THREADS}
    INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install -j $ENV{BUILD_THREADS}
  )
  add_custom_target(install_all ALL DEPENDS absl_static absl_shared)
else()
  add_custom_target(install_all ALL DEPENDS absl_static)
endif()

If you truly want Multi-Config (not just “Ninja”), detect and prefer it:

if cmake --help | grep -q "Ninja Multi-Config"; then
  cmake -G "Ninja Multi-Config" -DABSEIL_CPP_SOURCE_DIR="${ABSEIL_CPP_SOURCE_DIR}" .
  cmake --build . --target install_all --config Release -j"${BUILD_THREADS}"
elif command -v ninja >/dev/null 2>&1; then
  cmake -G Ninja -DABSEIL_CPP_SOURCE_DIR="${ABSEIL_CPP_SOURCE_DIR}" .
  ninja install_all -j"${BUILD_THREADS}"
else
  cmake -DABSEIL_CPP_SOURCE_DIR="${ABSEIL_CPP_SOURCE_DIR}" .
  make install_all -j"${BUILD_THREADS}"
fi

Thanks,
Michael Mendy

…ne pass

Historically, Abseil does not support shared libraries on Windows, and building both static and shared variants in a single workflow can be tricky. This change introduces a simplified CMake Superbuild that uses two ExternalProject calls to build static and shared libraries separately, while allowing them to coexist under the same install prefix.

The Superbuild is wrapped in a Bash script and uses Ninja Multi-Config when available to improve build speed and parallelism. This approach ensures both variants are installed in one execution without duplicating source checkout
steps.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant