You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake中链接含内部静态库的共享库时,如何避免导出内部目标

Solution to CMake Export Error When Wrapping Static Libraries into a Shared Library

Let's break down your problem and walk through the solutions step by step:

Why the Error Happens

When you link mysublib as PUBLIC to mylib, CMake adds mysublib to mylib's INTERFACE_LINK_LIBRARIES property. This means any target that links against mylib will also depend on mysublib. When you run export(TARGETS mylib), CMake checks all dependencies in the interface chain—since mysublib is a local target (not an imported one) and isn't included in the export set, it throws that error.

As for SystemC::systemc, it's an imported target (created by find_package(SystemCLanguage)). CMake recognizes imported targets as external dependencies managed by their own packages, so it doesn't require you to include them in your export set. Users of your library will just need to run find_package(SystemCLanguage) themselves to resolve that dependency.

How to Hide Internal Static Libraries from Exports

You have two main approaches to avoid exposing mysublib while still retaining the necessary interface information (like include paths, compile definitions) in mylib:

1. Merge Static Library Symbols into the Shared Library

The cleanest way is to link mysublib as PRIVATE to mylib, then manually transfer any required interface properties from mysublib to mylib's INTERFACE scope. This way, mysublib's symbols are embedded into mylib, and users only need to link against mylib without knowing about mysublib.

First, ensure your static library uses position-independent code (required for linking into a shared library):

set_target_properties(mysublib PROPERTIES POSITION_INDEPENDENT_CODE ON)

Then adjust your linking and property transfer:

# Link mysublib privately so it's not added to mylib's interface dependencies
target_link_libraries(mylib PUBLIC SystemC::systemc PRIVATE mysublib)

# Transfer mysublib's interface include directories to mylib's public interface
target_include_directories(mylib PUBLIC $<TARGET_PROPERTY:mysublib,INTERFACE_INCLUDE_DIRECTORIES>)

# Transfer any other interface properties (like compile definitions) if needed
target_compile_definitions(mylib PUBLIC $<TARGET_PROPERTY:mysublib,INTERFACE_COMPILE_DEFINITIONS>)

Now when you run export(TARGETS mylib NAMESPACE MyLib:: FILE MyLibTargets.cmake), CMake won't require mysublib to be exported because it's no longer part of mylib's interface chain.

2. Mark Internal Targets as Not Exportable (Advanced)

If you need to keep mysublib as a PUBLIC link for some reason, you can tell CMake to exclude it from the export dependency check by setting the EXPORT_NO_PACKAGE_REGISTRY property, but this is less recommended because it can break dependency resolution for users. Alternatively, use install(EXPORT) with careful management of the INTERFACE_LINK_LIBRARIES property to remove mysublib from the public interface.

But the first approach is far more straightforward and maintainable.

Do You Need to Package Internal Libraries as Imported Targets?

No, you don't need to go through the hassle of turning mysublib into a separate package and imported target. The methods above let you keep mysublib as an internal target while hiding it from your exported package configuration. Imported targets are useful for external dependencies, not internal libraries within the same project.


内容的提问来源于stack exchange,提问作者maloo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 21:42:34