You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[feature] Add option to consume unvendored libunwind #1714
As the project Sentry native is packaged in Conan Center already, and during our last review conan-io/conan-center-index#29690 was spotted a room for improvement, I'm sending this feature request / suggestion.
As Conan and other package managers can provide not only Sentry native, but also other dependencies, it would be great if we could manage libunwind as well, so consumers would not need to build that dependency from source too, when needed to use Sentry native.
As a suggestion, you could add a CMake option like WITH_EXTERNAL_LIBUNWIND, then use a logic like:
As a result, it would be possible to combine libunwind from the system, or the package manager. It's true libunwind does not provide an official CMake config file, but it could be easily wrapped by the consumer or the package manager (Conan provides one automatically).
Hi, thanks for the suggestion. Is Conan's libunwind built with -fPIC? I recall one of the reasons for vendoring libunwind was that the static libunwind available in Ubuntu repos is not.
@jpnurmi Hello! Yes, Conan builds with fPIC by default. The fPIC is part of a default option, which means, users can choose building with/without fPIC; the Conan Center CI service always builds the package with fPIC enabled.
One important bit of context: before #1446, sentry-native did support an unvendored/system libunwind path, but it intentionally kept static/shared selection under sentry-native’s control instead of using find_package.
The old logic had an explicit SENTRY_LIBUNWIND_SHARED option and selected either unwind or the exact libunwind.a archive:
That distinction matters because pkg-config typically provides -lunwind and private deps such as -llzma, but it does not force CMake to use the static archive.
If sentry-native adds a system-libunwind option, does Conan still need the same explicit shared/static control? Rather than only relying on:
From the sentry-native side, I think the main uncertainty is less about adding a CMake switch and more about making sure the resulting behavior is correct for downstream consumers. In particular, we would need to understand how this should handle:
shared vs. static libunwind selection, since that affects deployment and transitive link requirements
libunwind’s own dependencies, especially for static linking, such as lzma
ambiguity between libunwind / unwind library and target names
the exact imported target sentry-native should link against
how the dependency is represented in sentry-native’s installed CMake package
The last point is especially important: it is possible for the sentry-native build itself to succeed, but for downstream consumers to fail later if the installed/exported sentry::sentry target does not carry the right external dependency information.
We do have a couple of Alpine/musl CI jobs that could potentially run tests against a system-libunwind. That could give some coverage for general system-libunwind support, but it would not fully validate the Conan/package-manager case, though, and Ubuntu runners are not a great proxy here because the distro static-libunwind situation was one of the reasons sentry-native started vendoring libunwind in the first place...
@uilianries, would it make sense to explore this from the Conan side first, and then use that as the basis for a concrete sentry-native proposal?
If sentry-native adds a system-libunwind option, does Conan still need the same explicit shared/static control? Rather than only relying on:
@jpnurmi No. Conan is able to manage the entire dependencies graph based on settings and options, which, consumer can decide about being static/shared, but transitive dependencies will be always solved automatically by Conan as well, so there is no risk, this scenario is well mapped. You can understand a bit better how Conan compute dependencies by checking the documentation: https://docs.conan.io/2/reference/binary_model/package_id.html
P.S. For Conan Center, the libunwind recipe seems to define a component named unwind so you'd probably want to have libunwind::unwind instead of libunwind::libunwind?
The component name does not reflect the CMake target name: Components are independent and only used across Conan recipes to identify as a dependency. The CMake target name is name by the property cmake_target_name. For this specific case, we don't use one for libunwind because its upstream does not provide an official CMake config file or Findxxx.cmake file, so we just keep the package name as CMake target name: libunwind::libunwind.
Still, you can use libunwind::unwind if you want: Conan can model it on-the-fly, when building sentry-native as well. The CMakeDeps generator can set cmake_taget_name as well, so in case Sentry Native dicide to unwind::unwind or whatever, we still can adjust in Sentry Native's Conan recipe without problem.
From the sentry-native side, I think the main uncertainty is less about adding a CMake switch and more about making sure the resulting behavior is correct for downstream consumers. In particular, we would need to understand how this should handle:
You concenrs are very valid, and make total sense when projects keep their dependencies vendorized to keep it very controlled. I'll try to explain as consuming using Conan.
shared vs. static libunwind selection, since that affects deployment and transitive link requirements
Mixing shared and static is possible, but avoidable in most cases, as it may result in breakages. For instance, you can consume Sentry Native as a shared library, but linked to libunwind and its dependencies as static. It would be something like:
This will say to Conan to install all dependencies as static library (fPIC is active by default), except for sentry-native version 0.14.0. But we actually build and distribute all shared or all static in Conan Center and in our CI.
Transitive dependencies, like lzma will be linked to libunwind as needed, the genenerated CMake config file by Conan, will list lzma there, so there is no risk of missing it.
libunwind’s own dependencies, especially for static linking, such as lzma
To illustrate better, Conan will generate libunwind-config.cmake and a Cmake config file for each transitive dependecy as well. The libunwind-Target-release.cmake, for instance, will contain:
Which lists its transitives dependencies. In case lzma has publid pre-compiler definitions, they will be listed in the generate cmake file for lzma and will be consumed automatically via Cmake, so no worries.
ambiguity between libunwind / unwind library and target names
As libunwind officially does not have a CMake config or component file, nor CMake has a public module for it, Conan uses the format <package_name>::<package_name>. But if you think libunwind::unwind is more suitable, feel free to use it. We still can update the Conan recipe to use CMakeDeps().set_property("libunwind", "cmake_target_name", "libunwind::unwind").
Doing a quick google I can find a few projects, including KDE, using FindLibunwind.cmake as a custom CMake module file, but nothing regarding CMake targets.
the exact imported target sentry-native should link against
The CMake target, by defaul will be libunwind::libunwind as commented before. The means of being static or shared, are part of the target type so you do not need to care about it directly, it will be embedded as a property in the target. In the end, this will result the same target for both static and shared.
When using it, will be consuming the correct imported target already.
how the dependency is represented in sentry-native’s installed CMake package
Do you mean when installing Sentry Native from source or when using Conan to build and distribute? As libunwind in this case is managed as an external dependency, it will be up to the consumer to manage it. But, in terms of using Conan to install Sentry Native, it could be done by:
This will install Sentry Native and all its dependencies, but also generate CMake config files for all them (e.g. sentry-native-config.cmake, libunwind-config.cmake, ...) and finally a CMake toolchain file to match the settings (e.g. Release or Debug) and to set the CMake module path to find those generated cmake files. You can check it more details in the documentation.
Now, if someone is actually building Sentry Native from source, by cloning your project and want to libunwind as an external dependency (e.g. via Conan), it's possible to add a conanfile.txt or do a similar command as the previous, by listing libunwind as the needed dependency, and them build Sentry Native as usual.
However, when installing Sentry Native (e.g. make install), it will install only Sentry Native. Unless is all static and libunwind (and its dependencies) are linked to Sentry Native already, it may cause a runtime error when trying to find its dependencies, so consumers will need to also configure where dependencies are installed too. This is a more hypothetical scenario, as it's usually not recommended, because if you use a tool to build, it's expected to stick with it later.
The last point is especially important: it is possible for the sentry-native build itself to succeed, but for downstream consumers to fail later if the installed/exported sentry::sentry target does not carry the right external dependency information.
Similar to the last question, but in case building with Conan it will not be a problem, because all dependencies will be mapped. But for who is building from Sentry Native from source, and consuming sentry::sentry later, your CMake config file will have a condition saying "I need libunwind" and Cmake will try to find it. In case not available in the system it will break. But I understand, when someone builds Sentry Native from source, including its dependencies are solved already, it should not be a problem later, as was understood how to manage them before.
We do have a couple of Alpine/musl CI jobs that could potentially run tests against a system-libunwind.
If you are interested, I can open a PR by adding a new build integrated with Conan. There is a Github Action for setup-conan that makes it much easier. I'll be glad to help.
would it make sense to explore this from the Conan side first, and then use that as the basis for a concrete sentry-native proposal?
Currently, the Sentry Native on Conan side is using libunwind already. For instance, you check our last builds on Linux, Mac and Windows: https://github.com/conan-io/conan-center-index/pull/29690/checks. To illustrate the dependencies graph, we have the following index for version 0.14.0
As you can see, libcurl is also managed by Conan, but I just preferred to keep small steps first, and only talk about libunwind for now.
Thank you for your time, not only for writing down those questions. I hope I have clarified all those points mentioned. Feel free to ask for more clarification or new questions.
I could also propose including in Sentry Native's documentation, by solving libunwind using Conan: Add a new section about external dependencies, like consuming libunwind from the system, from Conan, and even expand to other package managers in the future. I could open a PR as well, just let me know.
@uilianries Thanks for the detailed explanation. I understand the appeal of having an option to use an unvendored libunwind. For what it's worth, I was not trying to argue against adding such an option, but wanted to explain the technical reasons that originally led us to vendor libunwind. 🙂 I've put together a proposal and tested it with our Alpine builds:
@jpnurmi Thank you for spending your time on investigating it. Your concern is totally valid as changing a dependency will affect consumers. As per your PR: Using pkg-config sounds great too, as both consumers and Conan can use libunwind .pc file to find its headers and libraries.
Activity
linear-code commentedon May 12, 2026
NATIVE-187
jpnurmi commentedon May 12, 2026
Hi, thanks for the suggestion. Is Conan's libunwind built with
-fPIC? I recall one of the reasons for vendoring libunwind was that the static libunwind available in Ubuntu repos is not.sentry-native/vendor/libunwind/CMakeLists.txt
Line 283 in b94ca43
uilianries commentedon May 13, 2026
@jpnurmi Hello! Yes, Conan builds with
fPICby default. The fPIC is part of a default option, which means, users can choose building with/without fPIC; the Conan Center CI service always builds the package with fPIC enabled.jpnurmi commentedon May 13, 2026
One important bit of context: before #1446, sentry-native did support an unvendored/system libunwind path, but it intentionally kept static/shared selection under sentry-native’s control instead of using
find_package.The old logic had an explicit
SENTRY_LIBUNWIND_SHAREDoption and selected eitherunwindor the exactlibunwind.aarchive:sentry-native/CMakeLists.txt
Lines 621 to 635 in 27364c7
That distinction matters because pkg-config typically provides
-lunwindand private deps such as-llzma, but it does not force CMake to use the static archive.If sentry-native adds a system-libunwind option, does Conan still need the same explicit shared/static control? Rather than only relying on:
P.S. For Conan Center, the libunwind recipe seems to define a component named
unwindso you'd probably want to havelibunwind::unwindinstead oflibunwind::libunwind?https://github.com/conan-io/conan-center-index/blob/ec9ff87d27cf777b7e6b4f89d1c64c443c0a972a/recipes/libunwind/all/conanfile.py#L129-L137
jpnurmi commentedon May 15, 2026
From the sentry-native side, I think the main uncertainty is less about adding a CMake switch and more about making sure the resulting behavior is correct for downstream consumers. In particular, we would need to understand how this should handle:
lzmalibunwind/unwindlibrary and target namesThe last point is especially important: it is possible for the sentry-native build itself to succeed, but for downstream consumers to fail later if the installed/exported
sentry::sentrytarget does not carry the right external dependency information.We do have a couple of Alpine/musl CI jobs that could potentially run tests against a system-libunwind. That could give some coverage for general system-libunwind support, but it would not fully validate the Conan/package-manager case, though, and Ubuntu runners are not a great proxy here because the distro static-libunwind situation was one of the reasons sentry-native started vendoring libunwind in the first place...
@uilianries, would it make sense to explore this from the Conan side first, and then use that as the basis for a concrete sentry-native proposal?
uilianries commentedon May 19, 2026
@jpnurmi No. Conan is able to manage the entire dependencies graph based on settings and options, which, consumer can decide about being static/shared, but transitive dependencies will be always solved automatically by Conan as well, so there is no risk, this scenario is well mapped. You can understand a bit better how Conan compute dependencies by checking the documentation: https://docs.conan.io/2/reference/binary_model/package_id.html
The component name does not reflect the CMake target name: Components are independent and only used across Conan recipes to identify as a dependency. The CMake target name is name by the property
cmake_target_name. For this specific case, we don't use one forlibunwindbecause its upstream does not provide an official CMake config file or Findxxx.cmake file, so we just keep the package name as CMake target name:libunwind::libunwind.Still, you can use
libunwind::unwindif you want: Conan can model it on-the-fly, when building sentry-native as well. The CMakeDeps generator can setcmake_taget_nameas well, so in case Sentry Native dicide tounwind::unwindor whatever, we still can adjust in Sentry Native's Conan recipe without problem.You concenrs are very valid, and make total sense when projects keep their dependencies vendorized to keep it very controlled. I'll try to explain as consuming using Conan.
Mixing shared and static is possible, but avoidable in most cases, as it may result in breakages. For instance, you can consume Sentry Native as a shared library, but linked to libunwind and its dependencies as static. It would be something like:
This will say to Conan to install all dependencies as static library (fPIC is active by default), except for sentry-native version 0.14.0. But we actually build and distribute all shared or all static in Conan Center and in our CI.
Transitive dependencies, like lzma will be linked to libunwind as needed, the genenerated CMake config file by Conan, will list lzma there, so there is no risk of missing it.
As you may observed, the Conan recipe for libunwind has options to disable lzma dependency (enabled by default): https://github.com/conan-io/conan-center-index/blob/master/recipes/libunwind/all/conanfile.py#L63, then in the package's configuration, is listed libunwind needs lzma when intalling the package: https://github.com/conan-io/conan-center-index/blob/master/recipes/libunwind/all/conanfile.py#L133. The lzma is actually
xz_utilspackage name.To illustrate better, Conan will generate
libunwind-config.cmakeand a Cmake config file for each transitive dependecy as well. Thelibunwind-Target-release.cmake, for instance, will contain:Which lists its transitives dependencies. In case lzma has publid pre-compiler definitions, they will be listed in the generate cmake file for lzma and will be consumed automatically via Cmake, so no worries.
As libunwind officially does not have a CMake config or component file, nor CMake has a public module for it, Conan uses the format
<package_name>::<package_name>. But if you thinklibunwind::unwindis more suitable, feel free to use it. We still can update the Conan recipe to useCMakeDeps().set_property("libunwind", "cmake_target_name", "libunwind::unwind").Doing a quick google I can find a few projects, including KDE, using
FindLibunwind.cmakeas a custom CMake module file, but nothing regarding CMake targets.The CMake target, by defaul will be
libunwind::libunwindas commented before. The means of being static or shared, are part of the target type so you do not need to care about it directly, it will be embedded as a property in the target. In the end, this will result the same target for both static and shared.When using it, will be consuming the correct imported target already.
Do you mean when installing Sentry Native from source or when using Conan to build and distribute? As libunwind in this case is managed as an external dependency, it will be up to the consumer to manage it. But, in terms of using Conan to install Sentry Native, it could be done by:
This will install Sentry Native and all its dependencies, but also generate CMake config files for all them (e.g. sentry-native-config.cmake, libunwind-config.cmake, ...) and finally a CMake toolchain file to match the settings (e.g. Release or Debug) and to set the CMake module path to find those generated cmake files. You can check it more details in the documentation.
Now, if someone is actually building Sentry Native from source, by cloning your project and want to libunwind as an external dependency (e.g. via Conan), it's possible to add a
conanfile.txtor do a similar command as the previous, by listing libunwind as the needed dependency, and them build Sentry Native as usual.However, when installing Sentry Native (e.g. make install), it will install only Sentry Native. Unless is all static and libunwind (and its dependencies) are linked to Sentry Native already, it may cause a runtime error when trying to find its dependencies, so consumers will need to also configure where dependencies are installed too. This is a more hypothetical scenario, as it's usually not recommended, because if you use a tool to build, it's expected to stick with it later.
Similar to the last question, but in case building with Conan it will not be a problem, because all dependencies will be mapped. But for who is building from Sentry Native from source, and consuming
sentry::sentrylater, your CMake config file will have a condition saying "I need libunwind" and Cmake will try to find it. In case not available in the system it will break. But I understand, when someone builds Sentry Native from source, including its dependencies are solved already, it should not be a problem later, as was understood how to manage them before.If you are interested, I can open a PR by adding a new build integrated with Conan. There is a Github Action for setup-conan that makes it much easier. I'll be glad to help.
Currently, the Sentry Native on Conan side is using libunwind already. For instance, you check our last builds on Linux, Mac and Windows: https://github.com/conan-io/conan-center-index/pull/29690/checks. To illustrate the dependencies graph, we have the following index for version 0.14.0
As you can see, libcurl is also managed by Conan, but I just preferred to keep small steps first, and only talk about libunwind for now.
Thank you for your time, not only for writing down those questions. I hope I have clarified all those points mentioned. Feel free to ask for more clarification or new questions.
I could also propose including in Sentry Native's documentation, by solving libunwind using Conan: Add a new section about external dependencies, like consuming libunwind from the system, from Conan, and even expand to other package managers in the future. I could open a PR as well, just let me know.
Regards.
mujacica commentedon May 25, 2026
Hey @uilianries, let us discuss this internally and we will get back to you
jpnurmi commentedon May 26, 2026
@uilianries Thanks for the detailed explanation. I understand the appeal of having an option to use an unvendored libunwind. For what it's worth, I was not trying to argue against adding such an option, but wanted to explain the technical reasons that originally led us to vendor libunwind. 🙂 I've put together a proposal and tested it with our Alpine builds:
SENTRY_LIBUNWIND_SYSTEMoption #1753uilianries commentedon May 26, 2026
@jpnurmi Thank you for spending your time on investigating it. Your concern is totally valid as changing a dependency will affect consumers. As per your PR: Using pkg-config sounds great too, as both consumers and Conan can use libunwind .pc file to find its headers and libraries.
uilianries commentedon May 27, 2026
@jpnurmi Thank you for all your support!