Skip to content

Commit

Permalink
Improve rerun_cpp readme & CMakeLists.txt (#4126)
Browse files Browse the repository at this point in the history
### What

* Fixes #4117
* overhauled Readme.md for rerun_cpp
* everything except is now part of rerun_cpp zip bundle
* made rerun_cpp CMakeLists.txt smaller by splitting out the from-source
rerun_c and the from-source arrow builds out
* rerun_c is now built as a built action, meaning it's part of the
buildgraph of whatever generator you use - e.g. Ninja will build it now
in parallel to your C files 🥳

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested [demo.rerun.io](https://demo.rerun.io/pr/4126) (if
applicable)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG

- [PR Build Summary](https://build.rerun.io/pr/4126)
- [Docs
preview](https://rerun.io/preview/1f68439ed4731c219b116fd41e15638015b9d68b/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/1f68439ed4731c219b116fd41e15638015b9d68b/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://ref.rerun.io/dev/bench/)
- [Wasm size tracking](https://ref.rerun.io/dev/sizes/)
  • Loading branch information
Wumpf committed Nov 3, 2023
1 parent 05de68b commit c62c6a3
Show file tree
Hide file tree
Showing 14 changed files with 280 additions and 208 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ endif()

# ------------------------------------------------------------------------------

function(set_default_warning_settings target)
function(rerun_strict_warning_settings target)
if(MSVC)
# TODO(andreas): Try to enable /Wall
target_compile_options(${target} PRIVATE /W4)
Expand Down Expand Up @@ -151,9 +151,9 @@ if(NOT WIN32)
set(LOGURU_STACKTRACES 1)
endif()


# ------------------------------------------------------------------------------
add_subdirectory(rerun_cpp) # The Rerun C++ SDK library
add_subdirectory(crates/rerun_c) # The Rerun C SDK library, must be included before the C++ SDK.
add_subdirectory(rerun_cpp) # The Rerun C++ SDK library.
add_subdirectory(examples/cpp)
add_subdirectory(tests/cpp)
add_subdirectory(docs/code-examples)
37 changes: 37 additions & 0 deletions crates/rerun_c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Builds rerun_c from source.

# Determine Rust's librerun path.
if(APPLE)
set(RERUN_C_BUILD_ARTIFACT ${CMAKE_CURRENT_SOURCE_DIR}/../../target/release/librerun_c.a)
elseif(UNIX) # if(LINUX) # CMake 3.25
set(RERUN_C_BUILD_ARTIFACT ${CMAKE_CURRENT_SOURCE_DIR}/../../target/release/librerun_c.a)
elseif(WIN32)
set(RERUN_C_BUILD_ARTIFACT ${CMAKE_CURRENT_SOURCE_DIR}/../../target/release/rerun_c.lib)
else()
message(FATAL_ERROR "Unsupported platform.")
endif()

# Setup rerun_c library
add_library(rerun_c STATIC IMPORTED GLOBAL)
set_target_properties(rerun_c PROPERTIES IMPORTED_LOCATION ${RERUN_C_BUILD_ARTIFACT})

# Just depend on all rust and toml files, it's hard to know which files exactly are relevant.
file(GLOB_RECURSE RERUN_C_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../crates/*.rs" "${CMAKE_CURRENT_SOURCE_DIR}/../crates/*.toml")
add_custom_command(
OUTPUT ${RERUN_C_BUILD_ARTIFACT}
DEPENDS ${RERUN_C_SOURCES}
COMMAND cargo build --release -p rerun_c
COMMENT "Building rerun_c from source"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..
)

# In CMake you can't depend on an output file directly. We have to wrap this in a target that rerun_c then depends on.
add_custom_target(rerun_c_build DEPENDS "${RERUN_C_BUILD_ARTIFACT}")
add_dependencies(rerun_c rerun_c_build)

# Put `rerun.h` into the same place where it's on a user's machine and apply CMake variables like version number.
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/src/rerun.h"
"${CMAKE_CURRENT_SOURCE_DIR}/../../rerun_cpp/src/rerun/c/rerun.h"
NEWLINE_STYLE LF # Specify line endings, otherwise CMake wants to change them on Windows.
)
2 changes: 1 addition & 1 deletion docs/code-examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ foreach(SOURCE_PATH ${sources_list})

add_executable(${EXAMPLE_TARGET} ${SOURCE_PATH})

set_default_warning_settings(${EXAMPLE_TARGET})
rerun_strict_warning_settings(${EXAMPLE_TARGET})
target_link_libraries(${EXAMPLE_TARGET} PRIVATE rerun_sdk)

add_dependencies(doc_examples ${EXAMPLE_TARGET})
Expand Down
2 changes: 1 addition & 1 deletion examples/cpp/clock/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16...3.27)
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_clock main.cpp)
set_default_warning_settings(example_clock)
rerun_strict_warning_settings(example_clock)
else()
project(example_clock LANGUAGES CXX)

Expand Down
2 changes: 1 addition & 1 deletion examples/cpp/custom_component_adapter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16...3.27)
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_custom_component_adapter main.cpp)
set_default_warning_settings(example_custom_component_adapter)
rerun_strict_warning_settings(example_custom_component_adapter)
else()
project(example_custom_component_adapter LANGUAGES CXX)

Expand Down
2 changes: 1 addition & 1 deletion examples/cpp/dna/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16...3.27)
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_dna main.cpp)
set_default_warning_settings(example_dna)
rerun_strict_warning_settings(example_dna)
else()
project(example_dna LANGUAGES CXX)

Expand Down
2 changes: 1 addition & 1 deletion examples/cpp/minimal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16...3.27)
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_minimal main.cpp)
set_default_warning_settings(example_minimal)
rerun_strict_warning_settings(example_minimal)
else()
project(example_minimal LANGUAGES CXX)

Expand Down
2 changes: 1 addition & 1 deletion examples/cpp/spawn_viewer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16...3.27)
# This can be done by passing `-DRERUN_CPP_URL=<path to rerun_sdk_cpp zip>` to cmake.
if(DEFINED RERUN_REPOSITORY)
add_executable(example_spawn_viewer main.cpp)
set_default_warning_settings(example_spawn_viewer)
rerun_strict_warning_settings(example_spawn_viewer)
else()
project(example_spawn_viewer LANGUAGES CXX)

Expand Down
225 changes: 37 additions & 188 deletions rerun_cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# ------------------------------------------------------------------------------
# Rerun C++ SDK
#
# For more information check README.md
# ------------------------------------------------------------------------------

cmake_minimum_required(VERSION 3.16...3.27)

message("Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION} (${CMAKE_CXX_COMPILER})")

# NOTE: CMake docs strongly discourages using GLOB, and instead suggests
# manually listing all the files, like it's 1972.
# However, that won't work for use since we auto-generate the source tree.
# See https://cmake.org/cmake/help/latest/command/file.html#glob
# ------------------------------------------------------------------------------
# Base setup for rerun_sdk C++ library.

file(GLOB_RECURSE rerun_sdk_SRC CONFIGURE_DEPENDS
"src/*.hpp"
"src/*.cpp"
Expand All @@ -24,44 +29,18 @@ if(MSVC)
target_compile_options(rerun_sdk PRIVATE "/MP")
endif()

# ------------------------------------------------------------------------------
# Rerun development setup only:
if(DEFINED RERUN_REPOSITORY)
# TODO(andreas): use add_custom_command instead so this runs at build time! https://cmake.org/cmake/help/latest/command/add_custom_command.html#command:add_custom_command
execute_process(COMMAND cargo build --release -p rerun_c RESULT_VARIABLE ret) # We link against this, so must be up-to-date

# execute process doesn't fail if the process fails.
# `COMMAND_ERROR_IS_FATAL ANY` parameter fixes this but is only available in CMake 3.19
if(NOT(ret EQUAL "0"))
message(FATAL_ERROR "Failed to build rerun_c.")
endif()

# Overwrite where to find rerun_c library.
if(APPLE)
set(RERUN_C_LIB_DEFAULT ${CMAKE_CURRENT_SOURCE_DIR}/../target/release/librerun_c.a)
elseif(UNIX) # if(LINUX) # CMake 3.25
set(RERUN_C_LIB_DEFAULT ${CMAKE_CURRENT_SOURCE_DIR}/../target/release/librerun_c.a)
elseif(WIN32)
set(RERUN_C_LIB_DEFAULT ${CMAKE_CURRENT_SOURCE_DIR}/../target/release/rerun_c.lib)
else()
message(FATAL_ERROR "Unsupported platform.")
endif()

# Set very strict warning settings when we're testing the SDK.
# We don't want to force this on any user!
set_default_warning_settings(rerun_sdk)

# Put `rerun.h` into the same place where it's on a user's machine and apply CMake variables like version number.
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/../crates/rerun_c/src/rerun.h"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rerun/c/rerun.h"
NEWLINE_STYLE LF # Specify line endings, otherwise CMake wants to change them on Windows.
)
# Set default warning settings if defined.
if (COMMAND rerun_strict_warning_settings)
message("Building Rerun C++ SDK with strict compilation warnings.")
rerun_strict_warning_settings(rerun_sdk)
endif()

# ------------------------------------------------------------------------------
# Setup rerun_c dependency:
if(NOT DEFINED RERUN_C_LIB_DEFAULT)
# Setup rerun_c dependency if it wasn't set up already.
if(NOT TARGET rerun_c)
add_library(rerun_c STATIC IMPORTED GLOBAL)

# Inside the repo build ourselves, otherwise default to a local `lib` folder.
set(RERUN_C_DEFAULT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/)

if(APPLE)
Expand All @@ -81,21 +60,18 @@ if(NOT DEFINED RERUN_C_LIB_DEFAULT)
else()
message(WARNING "Unsupported platform ${RERUN_C_LIB_DEFAULT}, can't find rerun_c library.")
endif()
endif()

set(RERUN_C_LIB ${RERUN_C_LIB_DEFAULT} CACHE PATH "\
Where to find the rerun_c library.\n\
If not specified, a local rerun_c with the current system architecture will be used."
)
set(RERUN_C_LIB ${RERUN_C_LIB_DEFAULT} CACHE PATH "\
Where to find the rerun_c library.\n\
If not specified, a local rerun_c with the current system architecture will be used."
)

if("${RERUN_C_LIB}" STREQUAL "")
message(FATAL_ERROR "RERUN_C_LIB is not set.")
endif()
if("${RERUN_C_LIB}" STREQUAL "")
message(FATAL_ERROR "RERUN_C_LIB is not set.")
endif()

# For cleanliness, create a rerun_c target with the correct dependencies.
# This allows other targets to depend on rerun_c directly if they need to.
add_library(rerun_c STATIC IMPORTED)
set_target_properties(rerun_c PROPERTIES IMPORTED_LOCATION ${RERUN_C_LIB})
set_target_properties(rerun_c PROPERTIES IMPORTED_LOCATION ${RERUN_C_LIB})
endif()

if(APPLE)
target_link_libraries(rerun_c INTERFACE "-framework CoreFoundation" "-framework IOKit")
Expand All @@ -108,159 +84,32 @@ endif()
target_link_libraries(rerun_sdk PRIVATE rerun_c)

# -----------------------------------------------------------------------------
# Arrow:
# Arrow dependency.
# This makes the setup a lot easier on Windows where we otherwise need to put Arrow.dll either in path or copy it with the executable.
# Additionally reduces risk of picking up system libraries on Mac / Linux.
set(RERUN_ARROW_LINK_SHARED_DEFAULT OFF)
option(RERUN_ARROW_LINK_SHARED "Link to the Arrow shared library" ${RERUN_ARROW_LINK_SHARED_DEFAULT})
option(RERUN_DOWNLOAD_AND_BUILD_ARROW "If enabled, arrow will be added as an external project and built with the minimal set required by the Rerun C++ SDK" ON)

if(RERUN_DOWNLOAD_AND_BUILD_ARROW)
include(ExternalProject)

set(ARROW_DOWNLOAD_PATH ${CMAKE_BINARY_DIR}/arrow)

if(RERUN_ARROW_LINK_SHARED)
set(ARROW_BUILD_SHARED ON)
set(ARROW_BUILD_STATIC OFF)

if(APPLE)
set(ARROW_LIBRARY_FILE ${ARROW_DOWNLOAD_PATH}/lib/libarrow.dylib)
elseif(UNIX) # if(LINUX) # CMake 3.25
set(ARROW_LIBRARY_FILE ${ARROW_DOWNLOAD_PATH}/lib/libarrow.so)
elseif(WIN32)
set(ARROW_LIBRARY_FILE ${ARROW_DOWNLOAD_PATH}/bin/arrow.dll)
else()
message(FATAL_ERROR "Unsupported platform.")
endif()
else()
set(ARROW_BUILD_SHARED OFF)
set(ARROW_BUILD_STATIC ON)

if(APPLE)
set(ARROW_LIBRARY_FILE ${ARROW_DOWNLOAD_PATH}/lib/libarrow.a)
set(ARROW_BUNDLED_DEPENDENCIES_FILE ${ARROW_DOWNLOAD_PATH}/lib/libarrow_bundled_dependencies.a)
elseif(UNIX) # if(LINUX) # CMake 3.25
set(ARROW_LIBRARY_FILE ${ARROW_DOWNLOAD_PATH}/lib/libarrow.a)
set(ARROW_BUNDLED_DEPENDENCIES_FILE ${ARROW_DOWNLOAD_PATH}/lib/libarrow_bundled_dependencies.a)
elseif(WIN32)
set(ARROW_LIBRARY_FILE ${ARROW_DOWNLOAD_PATH}/lib/arrow_static.lib)
set(ARROW_BUNDLED_DEPENDENCIES_FILE ${ARROW_DOWNLOAD_PATH}/lib/arrow_bundled_dependencies.lib)
else()
message(FATAL_ERROR "Unsupported platform.")
endif()
endif()


if(MSVC)
# Enable multithreaded compiling of Arrow on MSVC.
set(ARROW_CXXFLAGS "/MP")
# ASAN doesn't work with arrow (yet?)
set(ARROW_ASAN OFF)
else()
set(ARROW_CXXFLAGS "")
set(ARROW_ASAN ${RERUN_USE_ASAN})
endif()

# Workaround for https://github.com/apache/arrow/issues/36117
# This works around linking issues on Windows we got after enabling mimalloc.
if(MSVC)
file(MAKE_DIRECTORY ${ARROW_DOWNLOAD_PATH}/src/arrow_cpp-build/debug/)
file(MAKE_DIRECTORY ${ARROW_DOWNLOAD_PATH}/src/arrow_cpp-build/relwithdebinfo/)
file(MAKE_DIRECTORY ${ARROW_DOWNLOAD_PATH}/src/arrow_cpp-build/release/)
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(ARROW_CMAKE_PRESET ninja-debug-minimal)
else()
set(ARROW_CMAKE_PRESET ninja-release-minimal)
endif()

ExternalProject_Add(
arrow_cpp
PREFIX ${ARROW_DOWNLOAD_PATH}
GIT_REPOSITORY https://github.com/apache/arrow.git
GIT_TAG apache-arrow-10.0.1
GIT_SHALLOW ON
GIT_PROGRESS OFF # Git progress sounds like a nice idea but is in practive very spammy.

# LOG_X ON means that the output of the command will
# be logged to a file _instead_ of printed to the console.
LOG_CONFIGURE ON
LOG_BUILD ON
LOG_INSTALL ON

CMAKE_ARGS
--preset ${ARROW_CMAKE_PRESET}
-DARROW_BOOST_USE_SHARED=OFF
-DARROW_BUILD_SHARED=${ARROW_BUILD_SHARED}
-DARROW_BUILD_STATIC=${ARROW_BUILD_STATIC}
-DARROW_CXXFLAGS=${ARROW_CXXFLAGS}
-DARROW_IPC=ON
-DARROW_JEMALLOC=OFF # We encountered some build issues with jemalloc, use mimalloc instead.
-DARROW_MIMALLOC=ON
-DARROW_USE_ASAN=${ARROW_ASAN}
-DARROW_USE_TSAN=OFF
-DARROW_USE_UBSAN=OFF
-DBOOST_SOURCE=BUNDLED
-DCMAKE_INSTALL_PREFIX=${ARROW_DOWNLOAD_PATH}
-Dxsimd_SOURCE=BUNDLED
-DBOOST_SOURCE=BUNDLED
-DARROW_BOOST_USE_SHARED=OFF
-DARROW_CXXFLAGS=${DARROW_CXXFLAGS}
SOURCE_SUBDIR cpp
BUILD_BYPRODUCTS ${ARROW_LIBRARY_FILE} ${ARROW_BUNDLED_DEPENDENCIES_FILE}
)

# arrow_cpp target is not a library. Assemble one from it.
if(RERUN_ARROW_LINK_SHARED)
add_library(RerunArrowTarget SHARED IMPORTED)

# For windows we need to know both the dll AND the import library.
if(WIN32)
set_target_properties(RerunArrowTarget PROPERTIES IMPORTED_IMPLIB ${ARROW_DOWNLOAD_PATH}/lib/arrow.lib)
endif()
else()
add_library(RerunArrowTarget STATIC IMPORTED)

# Need to set the ARROW_STATIC define, otherwise arrow functions are dllimport decorated on Windows.
target_compile_definitions(RerunArrowTarget INTERFACE ARROW_STATIC)

# We have to explicitly opt in the arrow bundled dependencies, otherwise we're missing the symbols for mimalloc.
add_library(RerunArrowTargetBundledDeps STATIC IMPORTED)
add_dependencies(RerunArrowTargetBundledDeps arrow_cpp)
set_target_properties(RerunArrowTargetBundledDeps PROPERTIES
IMPORTED_LOCATION ${ARROW_BUNDLED_DEPENDENCIES_FILE}
)
target_link_libraries(RerunArrowTarget INTERFACE RerunArrowTargetBundledDeps)
endif()

add_dependencies(RerunArrowTarget arrow_cpp)
set_target_properties(RerunArrowTarget PROPERTIES
IMPORTED_LOCATION ${ARROW_LIBRARY_FILE}
INTERFACE_INCLUDE_DIRECTORIES ${ARROW_DOWNLOAD_PATH}/include
)

# Hack to propagate INTERFACE_INCLUDE_DIRECTORIES.
# via https://stackoverflow.com/a/47358004
file(MAKE_DIRECTORY ${ARROW_DOWNLOAD_PATH}/include)
include(download_and_build_arrow.cmake)
download_and_build_arrow() # populates `rerun_arrow_target`
else()
find_package(Arrow REQUIRED)

if(RERUN_ARROW_LINK_SHARED)
message(STATUS "Arrow SO version: ${ARROW_FULL_SO_VERSION}")
add_library(RerunArrowTarget ALIAS Arrow::arrow_shared)
add_library(rerun_arrow_target ALIAS Arrow::arrow_shared)
else()
message(STATUS "Arrow version: ${ARROW_VERSION}")
add_library(RerunArrowTarget ALIAS Arrow::arrow_static)
add_library(rerun_arrow_target ALIAS Arrow::arrow_static)
endif()
endif()

target_link_libraries(rerun_sdk PRIVATE RerunArrowTarget)
target_link_libraries(rerun_sdk PRIVATE rerun_arrow_target)


# -----------------------------------------------------------------------------
# Add test subfolder if we're inside the Rerun repository
# (we don't ship them in our fetch-content bundle)
if(DEFINED RERUN_REPOSITORY)
# Add tests if they exist (they are not part of the distribution zip).
# Has direct dpeendency to arrow, so needs to happen last.
if(EXISTS tests)
add_subdirectory(tests)
endif()

0 comments on commit c62c6a3

Please sign in to comment.