#9349·lynx

[Bug]: LynxDevtool 4.1.0 fails to link as a dynamic framework: duplicate symbol _LynxRegisterRTSInspectorManagerFactory

Author: OhKanghoonCreated Sep 9, 2026Updated Sep 9, 2026

System Info

  • Lynx: 4.1.0 (also present on develop @ a2814b92c; not present in 4.0.2)
  • Pods: LynxDevtool 4.1.0 from https://github.com/lynx-family/Specs
  • Integration: CocoaPods use_frameworks! with dynamic linkage
  • Xcode 15.2 (CI) and Xcode 26.4.1 (local) — toolchain independent

Details

LynxDevtool 4.1.0 fails to link as a dynamic framework with a duplicate symbol:

duplicate symbol '_LynxRegisterRTSInspectorManagerFactory' in:
    .../LynxDevtool.build/Objects-normal/x86_64/rts_inspector_manager_factory_stub.o
    .../LynxDevtool.build/Objects-normal/x86_64/rts_inspector_manager_factory_stub_ios.o
ld: 1 duplicate symbols
clang: error: linker command failed with exit code 1

Cause: the rts_inspector_manager_factory_stub target in devtool/lynx_devtool/js_debug/BUILD.gn compiles rts_inspector_manager_factory_stub.cc and, on iOS, additionally rts_inspector_manager_factory_stub_ios.cc. Both files define extern "C" void LynxRegisterRTSInspectorManagerFactory(void). The generated LynxDevtool.podspec therefore lists both files under Framework/source_files.

The default CocoaPods integration (use_frameworks! :linkage => :static, as in explorer/darwin/ios/lynx_explorer/Podfile) does not hit this: with a static archive the linker only pulls the first member that defines the symbol. A dynamic framework links every object and fails. Anything that force-loads the static archive (-all_load, -force_load) would fail the same way.

rts_inspector_manager_factory_stub_ios.cc only declares LynxRegisterRTSInspectorManagerFactoryImpl; the sole definition is in the generic stub, and LynxDevToolNGDarwinDelegate.mm anchors it. So the generic stub must stay, and on iOS the registration entry point should come from the iOS stub only.

Reproduce link

No response

Reproduce Steps

  1. Podfile:
    ruby
    source 'https://github.com/lynx-family/Specs.git'
    source 'https://cdn.cocoapods.org/'
    target 'App' do
      use_frameworks!            # dynamic
      pod 'Lynx', '4.1.0'
      pod 'LynxDevtool', '4.1.0'
    end
  2. pod install
  3. xcodebuild archive -workspace App.xcworkspace -scheme Pods-App -sdk iphonesimulator -destination 'generic/platform=iOS Simulator'
  4. Linking LynxDevtool fails with the duplicate symbol above.

Minimal repro without Xcode — compile the two files for the iOS simulator with -DOS_IOS=1 and link them into a dylib:

xcrun --sdk iphonesimulator clang++ -std=gnu++17 -DOS_IOS=1 -I. ... -c rts_inspector_manager_factory_stub.cc rts_inspector_manager_factory_stub_ios.cc
xcrun --sdk iphonesimulator clang++ -dynamiclib rts_inspector_manager_factory_stub.o rts_inspector_manager_factory_stub_ios.o
# duplicate symbol '_LynxRegisterRTSInspectorManagerFactory'

A fix is proposed in the linked pull request.