5845f1a41d
This symbol is defined as a static member object inside of a boost detail header. When boost headers are used in a project that uses Boost in both the main binary as well as dlopen()'d shlibs, the top_ symbol gets duplicated and the metadata gets partitioned. We use the Boost shlib to unify both the main binary and the shlibs to use the same memory address for top_. This involves marking the templated object call_stack::top_ as "extern" and then declaring to Boost that we intend to use the shlibs.
170 lines
5.3 KiB
CMake
170 lines
5.3 KiB
CMake
cmake_minimum_required(VERSION 3.16)
|
|
project(salmanoff VERSION 0.01.000 LANGUAGES CXX)
|
|
|
|
include(CMakeDependentOption)
|
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DAPSS.cmake)
|
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/DebugOpts.cmake)
|
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake)
|
|
|
|
# Set C++ standard
|
|
set(CMAKE_CXX_STANDARD 20)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
|
|
# Build type
|
|
if(NOT CMAKE_BUILD_TYPE)
|
|
set(CMAKE_BUILD_TYPE Debug FORCE)
|
|
endif()
|
|
|
|
# Compiler flags
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
|
|
|
|
# Mind oscillator configuration
|
|
set(MIND_VOSCILLATOR_PERIOD_MS 33 CACHE STRING "Mind's virtual osc clock rate (ms)")
|
|
if(NOT MIND_VOSCILLATOR_PERIOD_MS GREATER 0)
|
|
message(FATAL_ERROR "MIND_VOSCILLATOR_PERIOD_MS must be a positive integer > 0")
|
|
endif()
|
|
math(EXPR MIND_VOSCILLATOR_FREQ_MS "1000 / ${MIND_VOSCILLATOR_PERIOD_MS}")
|
|
|
|
# Device manager reattacher configuration
|
|
set(MRNTT_DEVMGR_REATTACHER_PERIOD_MS 2000
|
|
CACHE STRING "Device manager reattacher period (ms)")
|
|
if(NOT MRNTT_DEVMGR_REATTACHER_PERIOD_MS GREATER 0)
|
|
message(FATAL_ERROR
|
|
"MRNTT_DEVMGR_REATTACHER_PERIOD_MS must be a positive integer > 0")
|
|
endif()
|
|
|
|
# Stimulus buffer frame period configuration
|
|
set(STIMBUFF_FRAME_PERIOD_MS 33
|
|
CACHE STRING "Stimulus buffer frame period (ms)")
|
|
if(NOT STIMBUFF_FRAME_PERIOD_MS GREATER 0)
|
|
message(FATAL_ERROR
|
|
"STIMBUFF_FRAME_PERIOD_MS must be a positive integer > 0")
|
|
endif()
|
|
|
|
# Stimulus buffer frame retry delay configuration
|
|
set(STIMBUFF_FRAME_RETRY_DELAY_MS 1
|
|
CACHE STRING "Stimulus buffer frame retry delay (ms)")
|
|
if(NOT STIMBUFF_FRAME_RETRY_DELAY_MS GREATER 0)
|
|
message(FATAL_ERROR
|
|
"STIMBUFF_FRAME_RETRY_DELAY_MS must be a positive integer > 0")
|
|
endif()
|
|
|
|
# World thread configuration
|
|
option(WORLD_USE_BODY_THREAD
|
|
"Use body thread for world component instead of separate world thread" OFF)
|
|
|
|
# Test configuration
|
|
option(ENABLE_TESTS "Enable building tests" OFF)
|
|
|
|
# Set the debug locks variable for config.h
|
|
if(ENABLE_DEBUG_LOCKS)
|
|
set(CONFIG_ENABLE_DEBUG_LOCKS TRUE)
|
|
endif()
|
|
|
|
# Set the world thread variable for config.h
|
|
if(WORLD_USE_BODY_THREAD)
|
|
set(CONFIG_WORLD_USE_BODY_THREAD TRUE)
|
|
endif()
|
|
|
|
# Set the timeout variable for config.h
|
|
set(CONFIG_DEBUG_QUTEX_DEADLOCK_TIMEOUT_MS ${DEBUG_QUTEX_DEADLOCK_TIMEOUT_MS})
|
|
# Set the stimulus buffer frame period variable for config.h
|
|
set(CONFIG_STIMBUFF_FRAME_PERIOD_MS ${STIMBUFF_FRAME_PERIOD_MS})
|
|
# Set the stimulus buffer frame retry delay variable for config.h
|
|
set(CONFIG_STIMBUFF_FRAME_RETRY_DELAY_MS ${STIMBUFF_FRAME_RETRY_DELAY_MS})
|
|
|
|
# Configure config.h
|
|
configure_file(
|
|
${CMAKE_CURRENT_SOURCE_DIR}/include/config.h.in
|
|
${CMAKE_CURRENT_BINARY_DIR}/include/config.h
|
|
@ONLY
|
|
)
|
|
|
|
# Include directories
|
|
include_directories(
|
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
|
${CMAKE_CURRENT_SOURCE_DIR}/smocore/include
|
|
${CMAKE_CURRENT_BINARY_DIR}/include
|
|
)
|
|
|
|
# Find core dependencies
|
|
# We cannot use header-only Boost.Asio because we need both our dlopen()'d
|
|
# libraries and the main binary to refer to the same instances of boost::asio's
|
|
# metadata. If we use header-only Boost.Asio, each dlopen()'d library will have
|
|
# its own copy of boost::asio's metadata, which will cause a segfault if
|
|
# boost::asio objects are used inside of a dlopen()'d library.
|
|
#
|
|
# Honestly, I never liked this whole "header-only" idea so I'm happy to be rid
|
|
# of it.
|
|
#
|
|
# Tell CMake we're linking against the shared library (not header-only)
|
|
set(Boost_USE_STATIC_LIBS OFF)
|
|
set(Boost_USE_HEADER_ONLY OFF)
|
|
find_package(Boost REQUIRED COMPONENTS system log)
|
|
find_package(PkgConfig REQUIRED)
|
|
find_package(FLEX REQUIRED)
|
|
find_package(BISON REQUIRED)
|
|
|
|
# Need dlopen() and dlsym()
|
|
find_library(DL_LIBRARY NAMES dl ldl)
|
|
if(NOT DL_LIBRARY)
|
|
message(FATAL_ERROR "Dynamic linking library (libdl/libldl) not found")
|
|
endif()
|
|
|
|
# Add third-party dependencies
|
|
if(ENABLE_TESTS)
|
|
add_subdirectory(third_party)
|
|
endif()
|
|
add_subdirectory(compile)
|
|
# Add core components
|
|
add_subdirectory(smocore)
|
|
add_subdirectory(commonLibs)
|
|
add_subdirectory(stimBuffApis)
|
|
add_subdirectory(wilzorApis)
|
|
add_subdirectory(devices)
|
|
|
|
# Main executable
|
|
add_executable(salmanoff main.cpp)
|
|
target_link_libraries(salmanoff
|
|
Boost::system Boost::log
|
|
smocore
|
|
${DL_LIBRARY}
|
|
)
|
|
|
|
# Verify Boost dynamic dependencies after build
|
|
add_custom_command(TARGET salmanoff POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -DVERIFY_FILE="$<TARGET_FILE:salmanoff>"
|
|
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/VerifyBoostDynamic.cmake
|
|
COMMENT "Verifying Boost dynamic dependencies for salmanoff"
|
|
)
|
|
|
|
# Add all registered DAPSS targets as dependencies
|
|
add_all_daps_dependencies()
|
|
|
|
# Add tests if enabled
|
|
if(ENABLE_TESTS)
|
|
enable_testing()
|
|
add_subdirectory(tests)
|
|
endif()
|
|
|
|
install(TARGETS salmanoff DESTINATION bin)
|
|
|
|
# Install device configuration files (preprocessed .daps files)
|
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/devices/
|
|
DESTINATION share/salmanoff/devices
|
|
FILES_MATCHING PATTERN "*.daps"
|
|
)
|
|
|
|
# Install documentation
|
|
install(FILES README.md DESTINATION share/doc/salmanoff)
|
|
install(FILES LICENSE DESTINATION share/doc/salmanoff)
|
|
|
|
# Install example configurations if they exist
|
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples")
|
|
install(DIRECTORY examples/ DESTINATION share/salmanoff/examples)
|
|
endif()
|
|
|
|
# Include CPack configuration
|
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CPackConfig.cmake)
|
|
include(CPack)
|