Skip to content
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

Improve rerun_cpp readme & CMakeLists.txt #4126

Merged
merged 15 commits into from
Nov 3, 2023
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
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbh I'm deeply confused (and troubled) about the visibility scope of cmake variables, so I don't know. Worst case this requires more patches then

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()
Loading
Loading