diff --git a/CHANGELOG.md b/CHANGELOG.md index f0432f8c7..cc75a73e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Add `pinocchio_python_parser` target ([#2475](https://github.com/stack-of-tasks/pinocchio/pull/2475)) +### Changed +- On GNU/Linux and macOS, hide all symbols by default ([#2469](https://github.com/stack-of-tasks/pinocchio/pull/2469)) + ## [3.3.0] - 2024-11-06 ### Added diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 3ddebe60c..e0f4a1e75 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -53,6 +53,7 @@ function(PINOCCHIO_PYTHON_BINDINGS_SPECIFIC_TYPE scalar_name) ${PYTHON_LIB_NAME} PROPERTIES PREFIX "" DEFINE_SYMBOL "${PYWRAP}_EXPORTS" + CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON) # Do not report: @@ -67,10 +68,10 @@ function(PINOCCHIO_PYTHON_BINDINGS_SPECIFIC_TYPE scalar_name) target_compile_options(${PYTHON_LIB_NAME} PRIVATE ${PRIVATE_OPTIONS}) set(PINOCCHIO_PYTHON_CONTEXT_FILE_VALUE "pinocchio/bindings/python/context/${scalar_name}.hpp") - target_compile_options( + target_compile_definitions( ${PYTHON_LIB_NAME} - PRIVATE -DPINOCCHIO_PYTHON_CONTEXT_FILE="${PINOCCHIO_PYTHON_CONTEXT_FILE_VALUE}" - -DPINOCCHIO_PYTHON_MODULE_NAME=${PYTHON_LIB_NAME}) + PRIVATE PINOCCHIO_PYTHON_CONTEXT_FILE="${PINOCCHIO_PYTHON_CONTEXT_FILE_VALUE}" + PINOCCHIO_PYTHON_MODULE_NAME=${PYTHON_LIB_NAME}) set_target_properties(${PYTHON_LIB_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) if(BUILD_WITH_COMMIT_VERSION) @@ -183,6 +184,14 @@ if(BUILD_PYTHON_INTERFACE) if(BUILD_WITH_CODEGEN_SUPPORT) pinocchio_python_bindings_specific_type(cppadcg cppadcg) + + # On osx, use default visiblitiy because of an issue with thread_local storage defined in + # cppad/cg/cg.hpp header (see + # https://github.com/stack-of-tasks/pinocchio/pull/2469#issuecomment-2461845127) + if(APPLE) + set_target_properties(${PYWRAP}_cppadcg PROPERTIES CXX_VISIBILITY_PRESET default) + endif() + # CPPAD_DEBUG_AND_RELEASE allow to mix debug and release versions of CppAD in the same program. target_compile_definitions( ${PYWRAP}_cppadcg PRIVATE PYCPPAD_EXCLUDE_EIGEN_NUMTRAITS_SPECIALIZATION diff --git a/development/scripts/misc/common_symbols.py b/development/scripts/misc/common_symbols.py new file mode 100755 index 000000000..ea759d6e0 --- /dev/null +++ b/development/scripts/misc/common_symbols.py @@ -0,0 +1,48 @@ +#! /usr/bin/env python3 +# Find common dynamics public symbols between shared libraries. + +import argparse +import itertools +import pathlib +import subprocess +import typing + + +def generate_symbols(shared_library: pathlib.Path) -> typing.Set[str]: + # Show symbol + # -D: Dynamic + # -C: Demangled + # -U: Defined + # -W: Non weak + result = subprocess.run( + ["nm", "-DCUW", "--format=sysv", str(shared_library)], + capture_output=True, + text=True, + ) + output = result.stdout + lines_split = (line.split("|") for line in output.splitlines() if "|" in line) + # Only keep lines with exported (upper case) symbols. + # `u` is also a global symbol, but if we always build with compatible libraries, + # there is no issue to find it in many places. + return set([line[0].strip() for line in lines_split if line[2].strip().isupper()]) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + prog="common_symbol", + description="Find common dynamics public symbols between shared libraries.", + ) + parser.add_argument("shared_libraries", nargs="+", type=pathlib.Path) + + args = parser.parse_args() + symbols = [ + (shared_library, generate_symbols(shared_library)) + for shared_library in args.shared_libraries + ] + + for lib1, lib2 in itertools.combinations(symbols, 2): + print(f"Common symbols between {lib1[0]} and {lib2[0]}") + common_symbols = lib1[1].intersection(lib2[1]) + for common in common_symbols: + print(f"\t{common}") + print() diff --git a/include/pinocchio/algorithm/contact-cholesky.hpp b/include/pinocchio/algorithm/contact-cholesky.hpp index e2ec77a76..c54941701 100644 --- a/include/pinocchio/algorithm/contact-cholesky.hpp +++ b/include/pinocchio/algorithm/contact-cholesky.hpp @@ -104,9 +104,7 @@ namespace pinocchio /// /// \brief Default constructor /// - ContactCholeskyDecompositionTpl() - { - } + ContactCholeskyDecompositionTpl() = default; /// /// \brief Constructor from a model. @@ -463,35 +461,10 @@ namespace pinocchio ///@} template - bool operator==(const ContactCholeskyDecompositionTpl & other) const - { - bool is_same = true; - - if (nv != other.nv || num_contacts != other.num_contacts) - return false; - - if ( - D.size() != other.D.size() || Dinv.size() != other.Dinv.size() || U.rows() != other.U.rows() - || U.cols() != other.U.cols()) - return false; - - is_same &= (D == other.D); - is_same &= (Dinv == other.Dinv); - is_same &= (U == other.U); - - is_same &= (parents_fromRow == other.parents_fromRow); - is_same &= (nv_subtree_fromRow == other.nv_subtree_fromRow); - is_same &= (last_child == other.last_child); - // is_same &= (rowise_sparsity_pattern == other.rowise_sparsity_pattern); - - return is_same; - } + bool operator==(const ContactCholeskyDecompositionTpl & other) const; template - bool operator!=(const ContactCholeskyDecompositionTpl & other) const - { - return !(*this == other); - } + bool operator!=(const ContactCholeskyDecompositionTpl & other) const; PINOCCHIO_COMPILER_DIAGNOSTIC_POP protected: @@ -702,10 +675,17 @@ namespace pinocchio } // namespace pinocchio -#include "pinocchio/algorithm/contact-cholesky.hxx" - +// Because of a GCC bug we should NEVER define a function that use ContactCholeskyDecompositionTpl +// before doing the explicit template instantiation. +// If we don't take care, GCC will not accept any visibility attribute when declaring the +// explicit template instantiation of the ContactCholeskyDecompositionTpl class. +// The warning message will look like this: type attributes ignored after type is already defined +// [-Wattributes] A minimal code example is added on the PR +// (https://github.com/stack-of-tasks/pinocchio/pull/2469) #if PINOCCHIO_ENABLE_TEMPLATE_INSTANTIATION #include "pinocchio/algorithm/contact-cholesky.txx" #endif // PINOCCHIO_ENABLE_TEMPLATE_INSTANTIATION +#include "pinocchio/algorithm/contact-cholesky.hxx" + #endif // ifndef __pinocchio_algorithm_contact_cholesky_hpp__ diff --git a/include/pinocchio/algorithm/contact-cholesky.hxx b/include/pinocchio/algorithm/contact-cholesky.hxx index d16f36928..ece0b0081 100644 --- a/include/pinocchio/algorithm/contact-cholesky.hxx +++ b/include/pinocchio/algorithm/contact-cholesky.hxx @@ -625,6 +625,41 @@ namespace pinocchio return res; } + template + template + bool ContactCholeskyDecompositionTpl::operator==( + const ContactCholeskyDecompositionTpl & other) const + { + bool is_same = true; + + if (nv != other.nv || num_contacts != other.num_contacts) + return false; + + if ( + D.size() != other.D.size() || Dinv.size() != other.Dinv.size() || U.rows() != other.U.rows() + || U.cols() != other.U.cols()) + return false; + + is_same &= (D == other.D); + is_same &= (Dinv == other.Dinv); + is_same &= (U == other.U); + + is_same &= (parents_fromRow == other.parents_fromRow); + is_same &= (nv_subtree_fromRow == other.nv_subtree_fromRow); + is_same &= (last_child == other.last_child); + // is_same &= (rowise_sparsity_pattern == other.rowise_sparsity_pattern); + + return is_same; + } + + template + template + bool ContactCholeskyDecompositionTpl::operator!=( + const ContactCholeskyDecompositionTpl & other) const + { + return !(*this == other); + } + namespace details { diff --git a/pixi.lock b/pixi.lock index 8117ecf80..a1a8a2023 100644 --- a/pixi.lock +++ b/pixi.lock @@ -3884,6 +3884,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pycppad-1.2.4-py312h13dac87_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyngrok-7.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.0-pyhd8ed1ab_1.conda @@ -4044,6 +4045,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pycppad-1.2.4-py312h331613c_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyngrok-7.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.0-pyhd8ed1ab_1.conda @@ -4183,6 +4185,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pycppad-1.2.4-py312h117753f_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyngrok-7.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.0-pyhd8ed1ab_1.conda @@ -4229,6 +4232,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/console_bridge-1.0.2-h5362a0b_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.0-py312hd5eb7cc_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cppad-20230000.0-h63175ca_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.8.0-h91493d7_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/decorator-5.1.1-pyhd8ed1ab_0.tar.bz2 @@ -4312,6 +4316,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.48-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.3-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pycppad-1.2.4-py312h5714118_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyngrok-7.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.0-pyhd8ed1ab_1.conda diff --git a/pixi.toml b/pixi.toml index b959bc3a7..8236e4424 100644 --- a/pixi.toml +++ b/pixi.toml @@ -175,7 +175,8 @@ casadi = { features = ["casadi", "py312"], solve-group = "py312" } autodiff = { features = ["autodiff", "py312"], solve-group = "py312" } extra = { features = ["extra", "py312"], solve-group = "py312" } openmp = { features = ["openmp", "py312"], solve-group = "py312" } -codegen = { features = ["codegen", "py312"], solve-group = "py312" } +# codegen need autodiff +codegen = { features = ["autodiff", "codegen", "py312"], solve-group = "py312" } mpfr = { features = ["mpfr", "py312"], solve-group = "py312" } sdf = { features = ["sdf", "py312"], solve-group = "py312" } py39 = { features = ["py39"], solve-group = "py39" } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a46a56eb2..bcbb83da0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,7 +97,9 @@ function(PINOCCHIO_TARGET target_name) ${LIB_NAME} PROPERTIES LINKER_LANGUAGE CXX INSTALL_RPATH "\$ORIGIN" - VERSION ${PROJECT_VERSION}) + VERSION ${PROJECT_VERSION} + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON) endif() if(ENABLE_TEMPLATE_INSTANTIATION AND NOT ARGS_INTERFACE)