From 006d3d8e4a1f731ee677d7712d5af2159bfeb3b9 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 | 135 +++++++++++++++++++++++++++++++ dart/CMakeLists.txt | 7 ++ 3 files changed, 144 insertions(+), 3 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..a67672f8fdb8b 100644 --- a/cmake/dart_defs.cmake +++ b/cmake/dart_defs.cmake @@ -125,6 +125,141 @@ 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} + ) + + # 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 $