[CDRIVER-3431] Libraries linked with libmongoc overlinked if found via cmake Created: 17/Nov/19  Updated: 28/Oct/23  Resolved: 19/Nov/19

Status: Closed
Project: C Driver
Component/s: cmake
Affects Version/s: 1.15.2
Fix Version/s: 1.16.0

Type: Bug Priority: Major - P3
Reporter: Ryan Schmidt Assignee: Roberto Sanchez
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

macOS


Attachments: Text File overlinking.patch    

 Description   

On macOS 10.13.6, I have mongo-c-driver 1.15.2 installed with MacPorts, and then I built mongo-cxx-driver 3.4.0 and noticed that the library it installed is overlinked:

$ otool -L /opt/local/lib/libmongocxx.3.4.0.dylib
/opt/local/lib/libmongocxx.3.4.0.dylib:
	/opt/local/lib/libmongocxx._noabi.dylib (compatibility version 0.0.0, current version 3.4.0)
	/opt/local/lib/libbsoncxx._noabi.dylib (compatibility version 0.0.0, current version 3.4.0)
	/opt/local/lib/libmongoc-1.0.0.dylib (compatibility version 0.0.0, current version 0.0.0)
	/opt/local/lib/libbson-1.0.0.dylib (compatibility version 0.0.0, current version 0.0.0)
	/opt/local/lib/libsasl2.3.dylib (compatibility version 4.0.0, current version 4.0.0)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1455.11.0)
	/System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.70.14)
	/usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)
	/opt/local/lib/libsnappy.1.dylib (compatibility version 1.0.0, current version 1.1.7)
	/opt/local/lib/libicuuc.65.dylib (compatibility version 65.0.0, current version 65.1.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)

Those references to libsasl2, libresolv, libsnappy, libicuuc, and the Security and CoreFoundation frameworks should not be there because libmongocxx does not itself use them. Only its dependency libmongoc uses them.

I discovered that the reason for this is that mongo-cxx-driver finds out how to link with libmongoc by checking the file libmongoc-1.0-config.cmake. This file erroneously lists all of its dependencies; it should not since that's not needed for dynamic linking. (Compare with libmongoc-static-1.0-config.cmake which does and should list all of those dependencies, since it's needed for static linking.)

The problem would not have arisen if mongo-cxx-driver had used pkg-config instead of cmake to find mongo-c-driver, because mongo-c-driver's libmongoc-1.0.pc already correctly does not list those libraries in its Libs line:

$ pkg-config libmongoc-1.0 --libs
-L/opt/local/lib -lmongoc-1.0 -lbson-1.0

and libmongoc-static-1.0.pc also already correctly does list those libraries:

$ pkg-config libmongoc-static-1.0 --libs --static
-L/opt/local/lib -lmongoc-static-1.0 -lsasl2 -framework CoreFoundation -framework Security -lresolv -lz -lsnappy -lzstd -licuuc -lbson-static-1.0 /usr/lib/libm.dylib

I fixed it by removing the lines from libmongoc-1.0-config.cmake that add the libraries, as in the attached patch. After rebuilding mongo-cxx-driver with that, it's now linked like this:

$ otool -L /opt/local/lib/libmongocxx.3.4.0.dylib
/opt/local/lib/libmongocxx.3.4.0.dylib:
	/opt/local/lib/libmongocxx._noabi.dylib (compatibility version 0.0.0, current version 3.4.0)
	/opt/local/lib/libbsoncxx._noabi.dylib (compatibility version 0.0.0, current version 3.4.0)
	/opt/local/lib/libmongoc-1.0.0.dylib (compatibility version 0.0.0, current version 0.0.0)
	/opt/local/lib/libbson-1.0.0.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)

Much better.

The relevant file has already been removed from your git master due to CDRIVER-3047. I haven't tested master so I don't know if the problem still exists there.



 Comments   
Comment by Roberto Sanchez [ 19/Nov/19 ]

The old CMake scripts were written by hand for historical reasons. As part of CDRIVER-3047 we have already replaced them with improved scripts and the result is that the issue you identified has already been fixed. For example, building the C++ driver master branch against an installation of the C driver master branch results in:

readelf -d /tmp/mongo-cxx-driver/lib/libmongocxx.so | grep -w NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libmongoc-1.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libbsoncxx.so._noabi]
 0x0000000000000001 (NEEDED)             Shared library: [libbson-1.0.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

I also confirmed by inspecting the verbose build output of the C++ driver that we no longer pass superfluous library linkages out of the C driver.

Note that in CDRIVER-3413 we are restoring the old CMake scripts so as to not break existing workflows in the next release. We are considering whether your suggested patch is something we can include in that work.

Generated at Wed Feb 07 21:18:01 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.