rclcpp icon indicating copy to clipboard operation
rclcpp copied to clipboard

Confusion regarding visibility_control for static libraries for Windows

Open prnthp opened this issue 11 months ago • 2 comments

Looking at visibility_control.hpp (and all of these throughout the ROS2 codebase), it seems like it was never designed for static linkage on Windows. Say I don't have RCLCPP_BUILDING_LIBRARY in my preprocessor flags, RCLCPP_PUBLIC_TYPE will use __declspec(dllimport), which is probably not what you want during statically linking. Other libraries tend to just leave those defines blank --even the second example in the linked website in the header does that (https://gcc.gnu.org/wiki/Visibility).

Am I missing something fundamental here? C++ isn't my strong suite, but I'm trying to get static libraries instead of shared libraries/.dlls.

Thank you!

#ifndef RCLCPP__VISIBILITY_CONTROL_HPP_
#define RCLCPP__VISIBILITY_CONTROL_HPP_

// This logic was borrowed (then namespaced) from the examples on the gcc wiki:
//     https://gcc.gnu.org/wiki/Visibility

#if defined _WIN32 || defined __CYGWIN__
  #ifdef __GNUC__
    #define RCLCPP_EXPORT __attribute__ ((dllexport))
    #define RCLCPP_IMPORT __attribute__ ((dllimport))
  #else
    #define RCLCPP_EXPORT __declspec(dllexport)
    #define RCLCPP_IMPORT __declspec(dllimport)
  #endif
  #ifdef RCLCPP_BUILDING_LIBRARY
    #define RCLCPP_PUBLIC RCLCPP_EXPORT
  #else
    #define RCLCPP_PUBLIC RCLCPP_IMPORT
  #endif
  #define RCLCPP_PUBLIC_TYPE RCLCPP_PUBLIC
  #define RCLCPP_LOCAL
#else
  #define RCLCPP_EXPORT __attribute__ ((visibility("default")))
  #define RCLCPP_IMPORT
  #if __GNUC__ >= 4
    #define RCLCPP_PUBLIC __attribute__ ((visibility("default")))
    #define RCLCPP_LOCAL  __attribute__ ((visibility("hidden")))
  #else
    #define RCLCPP_PUBLIC
    #define RCLCPP_LOCAL
  #endif
  #define RCLCPP_PUBLIC_TYPE
#endif

#endif  // RCLCPP__VISIBILITY_CONTROL_HPP_

prnthp avatar Feb 14 '25 23:02 prnthp

It might be fine? This person had a similar question and said compiling static libraries on Windows with __declspec(...), and they reported the static library still worked. I wasn't able to find Microsoft docs on this from a quick search though.

https://stackoverflow.com/questions/69075958/is-declspecdllexport-ignored-if-compiling-a-static-library

sloretz avatar Feb 27 '25 18:02 sloretz

As far as I remember, static libraries on Windows are indeed broken by this, there are bunch of old comments on this scattered around in repos, but this is the most complete: https://github.com/ament/ament_cmake/issues/201#issuecomment-543898151 . As far as I remember, the root of the problem is that the boilerplate used in ROS 2 is based on the one available under "" section in https://gcc.gnu.org/wiki/Visibility, while the "correct" (i.e. "that supports compilation as static library on Windows") is the one under the "How to use the new C++ visibility support" section in the same page.

traversaro avatar Nov 07 '25 08:11 traversaro