From 82ee900c7399de018e6cddcbb6acaf7407642d07 Mon Sep 17 00:00:00 2001 From: Jeongseok Lee Date: Mon, 1 Apr 2024 17:17:48 -0700 Subject: [PATCH] [build] Set up symbol visibility for dart --- .github/workflows/ci_windows.yml | 5 +- cmake/dart_defs.cmake | 136 ++++++++++++++++++++++ dart/CMakeLists.txt | 7 ++ dart/common/Aspect.hpp | 2 +- dart/common/CAllocator.hpp | 2 +- dart/common/Console.hpp | 6 +- dart/common/MemoryAllocator.hpp | 2 +- dart/common/Uri.hpp | 1 + dart/dynamics/detail/ShapeFrameAspect.hpp | 2 +- dart/external/odelcpsolver/CMakeLists.txt | 2 +- dart/optimizer/Function.hpp | 4 +- dart/optimizer/Problem.hpp | 4 +- dart/optimizer/Solver.hpp | 4 +- pixi.toml | 2 +- 14 files changed, 165 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci_windows.yml b/.github/workflows/ci_windows.yml index 5d7240798d5c1..3e493577f9aed 100644 --- a/.github/workflows/ci_windows.yml +++ b/.github/workflows/ci_windows.yml @@ -22,14 +22,14 @@ on: jobs: build: - name: win-${{ matrix.build_type }} + name: win-${{ matrix.build_type }}-shared_libs=${{ matrix.build_shared_libs }} runs-on: windows-latest strategy: fail-fast: false matrix: toolset: [""] build_type: [Release] - build_shared_libs: [OFF] # TODO(JS): Add ON once shared lib build is resolved + build_shared_libs: [ON, OFF] steps: - name: Checkout @@ -73,7 +73,6 @@ jobs: -G "Visual Studio 17 2022" ^ -A x64 ^ -Wno-dev ${{ matrix.toolset }} ^ - -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} ^ -DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" ^ -DDART_MSVC_DEFAULT_OPTIONS=ON ^ -DDART_VERBOSE=ON ^ diff --git a/cmake/dart_defs.cmake b/cmake/dart_defs.cmake index ec1d05176134b..bb7935ee09cd1 100644 --- a/cmake/dart_defs.cmake +++ b/cmake/dart_defs.cmake @@ -125,6 +125,142 @@ function(dart_print_options) message(STATUS "") endfunction() +# cmake-format: off +# dart_check_compiler_visibility() +# +# Macro to check for visibility capability in compiler +# cmake-format: on +macro(dart_check_compiler_visibility variable) + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-fvisibility=hidden ${variable}) +endmacro() + +# dart_generate_export_header( +# TARGET_NAME +# DESTINATION +# INCLUDE_DIR +# EXPORT_FILE_NAME +# [BASE_NAME ] +# [EXPORT_ALL_SYMBOLS_BY_DEFAULT] +# ) +# +# Function to create an export header for control of binary symbols visibility +# +function(dart_generate_export_header) + set(prefix _ARG) + set(options EXPORT_ALL_SYMBOLS_BY_DEFAULT) + set(oneValueArgs + TARGET_NAME + DESTINATION + EXPORT_FILE_NAME + BASE_NAME + BASE_DIR + ) + set(multiValueArgs) + cmake_parse_arguments( + "${prefix}" + "${options}" + "${oneValueArgs}" + "${multiValueArgs}" + ${ARGN} + ) + + # Check required argument + if(NOT _ARG_TARGET_NAME) + message(FATAL_ERROR "DEVELOPER ERROR: You must specify TARGET_NAME!") + return() + endif() + if(NOT _ARG_DESTINATION) + message(FATAL_ERROR "DEVELOPER ERROR: You must specify DESTINATION!") + return() + endif() + if(NOT _ARG_EXPORT_FILE_NAME) + message(FATAL_ERROR "DEVELOPER ERROR: You must specify EXPORT_FILE_NAME!") + return() + endif() + + # Check if target is valid + if(NOT TARGET ${_ARG_TARGET_NAME}) + message( + FATAL_ERROR + "DEVELOPER ERROR: Invalid target " + "\"${_ARG_TARGET_NAME}\" is passed! " + "Make sure this function is called after the target is defined by " + "add_library( ...).") + return() + endif() + + # Hide symbols by default + if(UNIX AND NOT _ARG_EXPORT_ALL_SYMBOLS_BY_DEFAULT) + dart_check_compiler_visibility(compiler_supports_visibility) + if(compiler_supports_visibility) + target_compile_options(${_ARG_TARGET_NAME} PRIVATE -fvisibility=hidden) + endif() + endif() + + # Base name + if(_ARG_BASE_NAME) + set(base_name ${_ARG_BASE_NAME}) + else() + set(base_name "${_ARG_TARGET_NAME}") + string(REPLACE "-" "_" base_name ${base_name}) + endif() + string(TOUPPER ${base_name} base_name) + + # Set up paths + set(export_file_path "${_ARG_DESTINATION}/${_ARG_EXPORT_FILE_NAME}") + set(export_detail_file_path "${_ARG_DESTINATION}/detail/${_ARG_EXPORT_FILE_NAME}") + + # Generate CMake's default export header + include(GenerateExportHeader) + generate_export_header( + ${_ARG_TARGET_NAME} + EXPORT_MACRO_NAME DETAIL_${base_name}_API + EXPORT_FILE_NAME ${export_detail_file_path} + DEPRECATED_MACRO_NAME _DART_DEPRECATED + ) + + # Generate final export header + file( + WRITE ${export_file_path} + "// This file is automatically generated by ${PROJECT_NAME}.\n" + "\n" + "#pragma once\n" + "\n" + "/**\n" + " * @brief Apply this macro to classes and functions that will need to be exposed\n" + " to the consumer libraries or programs.\n" + " */\n" + "#define ${base_name}_API \\\n" + " DETAIL_${base_name}_API\n" + "\n" + "#ifdef _MSC_VER\n" + " #define ${base_name}_TEMPL_INST_DECL_API\n" + "#else\n" + " #define ${base_name}_TEMPL_INST_DECL_API ${base_name}_API\n" + "#endif\n" + "\n" + "#ifdef _MSC_VER\n" + " #define ${base_name}_TEMPL_INST_DEF_API ${base_name}_API\n" + "#else\n" + " #define ${base_name}_TEMPL_INST_DEF_API\n" + "#endif\n" + "\n" + "#include \"detail/${_ARG_EXPORT_FILE_NAME}\"\n" + ) + + # Install generated export files + set(include_base_path ${CMAKE_INSTALL_INCLUDEDIR}/${org_name}/${project_name}${project_version_major}) + set(export_install_path "${include_base_path}/${_ARG_BASE_DIR}") + set(detail_export_install_path "${export_install_path}/detail/") + install(FILES "${export_file_path}" + DESTINATION "${export_install_path}" + ) + install(FILES "${export_detail_file_path}" + DESTINATION "${detail_export_install_path}" + ) +endfunction() + function(dart_library) set(prefix _ARG) set(options diff --git a/dart/CMakeLists.txt b/dart/CMakeLists.txt index 3c547e94389f2..e85e794802499 100644 --- a/dart/CMakeLists.txt +++ b/dart/CMakeLists.txt @@ -114,6 +114,13 @@ get_property(dart_core_sources GLOBAL PROPERTY DART_CORE_SOURCES) # Add target dart_add_library(dart ${dart_core_headers} ${dart_core_sources}) +dart_generate_export_header( + TARGET_NAME dart + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} + EXPORT_FILE_NAME Export.hpp + BASE_NAME DART + BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR} +) target_include_directories(dart BEFORE PUBLIC $ diff --git a/dart/common/Aspect.hpp b/dart/common/Aspect.hpp index 07638453f87a0..d31096a4ccfb1 100644 --- a/dart/common/Aspect.hpp +++ b/dart/common/Aspect.hpp @@ -44,7 +44,7 @@ namespace common { class Composite; -class Aspect +class DART_API Aspect { public: friend class Composite; diff --git a/dart/common/CAllocator.hpp b/dart/common/CAllocator.hpp index 602988fa8d131..971431531b62e 100644 --- a/dart/common/CAllocator.hpp +++ b/dart/common/CAllocator.hpp @@ -39,7 +39,7 @@ namespace dart::common { /// A stateless memory allocator (in release mode) that uses std::malloc and /// std::free for memory allocation and deallocation. -class CAllocator : public MemoryAllocator +class DART_API CAllocator : public MemoryAllocator { public: /// Constructor diff --git a/dart/common/Console.hpp b/dart/common/Console.hpp index 5a1751b55b4f9..683351b0c56da 100644 --- a/dart/common/Console.hpp +++ b/dart/common/Console.hpp @@ -33,6 +33,8 @@ #ifndef DART_COMMON_CONSOLE_HPP_ #define DART_COMMON_CONSOLE_HPP_ +#include + #include #include @@ -52,10 +54,10 @@ namespace dart { namespace common { /// \brief -std::ostream& colorMsg(const std::string& _msg, int _color); +DART_API std::ostream& colorMsg(const std::string& _msg, int _color); /// \brief -std::ostream& colorErr( +DART_API std::ostream& colorErr( const std::string& _msg, const std::string& _file, unsigned int _line, diff --git a/dart/common/MemoryAllocator.hpp b/dart/common/MemoryAllocator.hpp index 0964c760d4cf2..101c7f81a2d8b 100644 --- a/dart/common/MemoryAllocator.hpp +++ b/dart/common/MemoryAllocator.hpp @@ -45,7 +45,7 @@ namespace dart::common { /// Base class for std::allocator compatible allocators. -class MemoryAllocator : public Castable +class DART_API MemoryAllocator : public Castable { public: /// Returns the default memory allocator diff --git a/dart/common/Uri.hpp b/dart/common/Uri.hpp index db31c0fa4695a..1dd3b06f8258f 100644 --- a/dart/common/Uri.hpp +++ b/dart/common/Uri.hpp @@ -33,6 +33,7 @@ #ifndef DART_COMMON_URI_HPP_ #define DART_COMMON_URI_HPP_ +#include #include namespace dart { diff --git a/dart/dynamics/detail/ShapeFrameAspect.hpp b/dart/dynamics/detail/ShapeFrameAspect.hpp index 7068cfed8c0a4..868c2c9737267 100644 --- a/dart/dynamics/detail/ShapeFrameAspect.hpp +++ b/dart/dynamics/detail/ShapeFrameAspect.hpp @@ -49,7 +49,7 @@ class ShapeFrame; namespace detail { -struct VisualAspectProperties +struct DART_API VisualAspectProperties { /// Color for the primitive shape Eigen::Vector4d mRGBA; diff --git a/dart/external/odelcpsolver/CMakeLists.txt b/dart/external/odelcpsolver/CMakeLists.txt index 1223df84340a1..b471ad7b05ee1 100644 --- a/dart/external/odelcpsolver/CMakeLists.txt +++ b/dart/external/odelcpsolver/CMakeLists.txt @@ -6,7 +6,7 @@ file(GLOB srcs "*.cpp") set(target_name ${PROJECT_NAME}-external-odelcpsolver) set(component_name external-odelcpsolver) -dart_add_library(${target_name} ${hdrs} ${srcs}) +dart_add_library(${target_name} STATIC ${hdrs} ${srcs}) target_include_directories(${target_name} PUBLIC $ diff --git a/dart/optimizer/Function.hpp b/dart/optimizer/Function.hpp index 90c3788f1a4cd..7eb1c455eb08d 100644 --- a/dart/optimizer/Function.hpp +++ b/dart/optimizer/Function.hpp @@ -33,6 +33,8 @@ #ifndef DART_OPTIMIZER_FUNCTION_HPP_ #define DART_OPTIMIZER_FUNCTION_HPP_ +#include + #include #include @@ -42,7 +44,7 @@ namespace dart { namespace optimizer { -class Function +class DART_API Function { public: /// Constructor diff --git a/dart/optimizer/Problem.hpp b/dart/optimizer/Problem.hpp index fdb95062d8785..8ce5c326561de 100644 --- a/dart/optimizer/Problem.hpp +++ b/dart/optimizer/Problem.hpp @@ -35,6 +35,8 @@ #include +#include + #include #include @@ -45,7 +47,7 @@ namespace dart { namespace optimizer { /// \brief class Problem -class Problem +class DART_API Problem { public: /// \brief Constructor diff --git a/dart/optimizer/Solver.hpp b/dart/optimizer/Solver.hpp index c1cb526ed173c..85017abae5571 100644 --- a/dart/optimizer/Solver.hpp +++ b/dart/optimizer/Solver.hpp @@ -33,6 +33,8 @@ #ifndef DART_OPTIMIZER_SOLVER_HPP_ #define DART_OPTIMIZER_SOLVER_HPP_ +#include + #include #include @@ -49,7 +51,7 @@ class Problem; /// problem types. This base class allows the different Solver implementations /// to be swapped out with each other quickly and easily to help with testing, /// benchmarking, and experimentation. -class Solver +class DART_API Solver { public: /// The Solver::Properties class contains Solver parameters that are common diff --git a/pixi.toml b/pixi.toml index 4be21adb8cd8e..3c8e58720b487 100644 --- a/pixi.toml +++ b/pixi.toml @@ -46,7 +46,7 @@ install-local = { cmd = "cmake --install build --prefix $CONDA_PREFIX", depends_ ] } configure-unix = { cmd = "cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release -DDART_VERBOSE=ON -DDART_USE_SYSTEM_IMGUI=ON" } -configure-win = { cmd = "cmake -S . -B build -G 'Visual Studio 17 2022' -DDART_VERBOSE=ON -DDART_MSVC_DEFAULT_OPTIONS=ON -DBUILD_SHARED_LIBS=OFF -DDART_USE_SYSTEM_IMGUI=OFF" } +configure-win = { cmd = "cmake -S . -B build -G 'Visual Studio 17 2022' -DDART_VERBOSE=ON -DDART_MSVC_DEFAULT_OPTIONS=ON -DBUILD_SHARED_LIBS=ON -DDART_USE_SYSTEM_IMGUI=OFF" } example-hello-world = { cmd = "cmake --build build --target hello_world --parallel && ./build/bin/hello_world", depends_on = [ "configure",