Skip to content

Commit

Permalink
Fix a build issue from iocore cleanup (#12000)
Browse files Browse the repository at this point in the history
* Fix a build issue from iocore cleanup

The build of test_net was broken on Mac when the build mode is set to
release.

Root cause:

We support two kinds of linkers.  One kind will only search for
symbols that are to the left of the object being linked.  Another kind
will search the list of libraries repeatedly until the no new undefined
references are created.  Both are sensitive to the order of libraries
on the command line.

In order to work with both, we have to carefully order our dependencies
in cmake.  See the build rule for traffic_server for a working list of
dependencies.

In this case, libinknet_stub.cc provides some symbols that are also
provided by ts::proxy, in order to fix an issue of cyclic dependency
between ts::inknet and ts::proxy.  However, this causes the link to
have duplicate symbols when libraries are not ordered correctly, on
linkers that repeat through the list.

References:

https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc

Solution:

For ld, use link groups so the linker searches the group repeatedly until symbols are resolved. 

For other linkers, carefully order the static libraries so the duplicate symbols are resolved before their stubs are seen.
  • Loading branch information
moonchen authored Feb 4, 2025
1 parent ef802cc commit 0dc80e8
Showing 1 changed file with 31 additions and 1 deletion.
32 changes: 31 additions & 1 deletion src/iocore/net/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,41 @@ if(TS_USE_LINUX_IO_URING)
endif()

if(BUILD_TESTING)
# libinknet_stub.cc is need because GNU ld is sensitive to the order of static libraries on the command line, and we have a cyclic dependency between inknet and proxy
add_executable(
test_net libinknet_stub.cc NetVCTest.cc unit_tests/test_ProxyProtocol.cc unit_tests/test_SSLSNIConfig.cc
unit_tests/test_YamlSNIConfig.cc unit_tests/unit_test_main.cc
)
target_link_libraries(test_net PRIVATE ts::inknet catch2::catch2)
if(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED OR CMAKE_CXX_LINK_GROUP_USING_RESCAN_SUPPORTED)
# Use link groups to solve circular dependency
set(LINK_GROUP_LIBS
ts::logging
ts::inknet
ts::inkhostdb
ts::proxy
ts::tsapibackend
ts::inkdns
ts::http2
ts::inkcache
ts::rpcpublichandlers
ts::overridable_txn_vars
ts::http
ts::http_remap
)
if(TS_USE_QUIC)
list(APPEND LINK_GROUP_LIBS quic http3)
endif()
string(JOIN "," LINK_GROUP_LIBS_CSV ${LINK_GROUP_LIBS})
target_link_libraries(
test_net PRIVATE catch2::catch2 ts::tscore "$<LINK_GROUP:RESCAN,${LINK_GROUP_LIBS_CSV}>" ts::tsutil ts::inkevent
libswoc::libswoc
)
else()
# These linkers already do the equivalent of RESCAN, so there's no support in cmake for it
# This case is mainly for macOS
# The reason that the list is different here, is because a careful ordering is necessary to prevent duplicate symbols, which are not allowed on macOS
target_link_libraries(test_net PRIVATE catch2::catch2 ts::tscore ts::proxy ts::inknet ts::inkevent libswoc::libswoc)
endif()
if(NOT APPLE)
target_link_options(test_net PRIVATE -Wl,--allow-multiple-definition)
endif()
Expand Down

0 comments on commit 0dc80e8

Please sign in to comment.