[CDRIVER-3225] Static libraries produced by cmake builds on Linux cannot be used without modification Created: 09/Jul/19  Updated: 28/Oct/23  Resolved: 25/Feb/20

Status: Closed
Project: C Driver
Component/s: Build
Affects Version/s: 1.14.0
Fix Version/s: 1.17.0-beta, 1.17.0

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

Ubuntu 16.04/18.04, quite possibly Linux in general



 Description   

It's possible that I simply don't understand the required intricacies of building with CMake. If so I apologise.

What am I doing
At my company we use libmongoc/libbson on different flavors of Ubuntu and Windows 10. We link statically against both libs because we want to keep the number of redistributables down to a minimum. MongoC and BSON are in most cases linked against a shared library which we distribute in-house. This was a breeze with 1.9.2 using automake, but seems to be slightly broken in 1.14.0 (possibly other versions as well).

Problem 1 (I consider this as being slightly broken)
Using the following CMake command, followed by make && make install results in static libraries that cannot be linked together since libmongoc-static-1.0.a will contain symbols that are also present in libbson-static-1.0.a.

CFLAGS=-fPIC CXXFLAGS=-fPIC cmake -DENABLE_ZLIB=BUNDLED -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_EXAMPLES=OFF -DENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release ../

The offending symbols are

bson_b64_initialize_rmap
bson_b64_ntop
bson_b64_pton
_bson_md5_append
_bson_md5_finish
_bson_md5_init
bson_md5_process

And the symptom of which is multiple definition errors when linking libmongoc and libbson against my artifact(s).
The workaround I ended up with here is to use objcopy to weaken the symbols in libmongoc-static-1.0.a post-build, before creating an archive and uploading it to our internal artifact storage for general consumption.

objcopy --weaken-symbol bson_b64_initialize_rmap --weaken-symbol bson_b64_ntop --weaken-symbol bson_b64_pton --weaken-symbol _bson_md5_append --weaken-symbol _bson_md5_finish --weaken-symbol _bson_md5_init --weaken-symbol bson_md5_process some_path_to/lib/libmongoc-static-1.0.a

Problem 2 (minor, but annoying)
Using the following CMake command, followed by make && make install results in static libraries that do not support relocation (i.e no -fPIC) and thus cannot be linked against a shared object.

cmake -DENABLE_ZLIB=BUNDLED -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_EXAMPLES=OFF -DENABLE_TESTS=OFF  -DCMAKE_BUILD_TYPE=Release ../

The workaround I used here was to simply set CFLAGS=-fPIC CXXFLAGS=-fPIC, but it would be nice if there was a proper build flag for setting them. Like ENABLE_PIC or something along those lines.

Problem 3 (confusing)
The libraries produced by building the CMake projects are not properly versioned. It's been 1.0 since forever.

The workaround for problem 1 seems overly hackish just to be able to use the static libraries. I'm not sure how you'd fix it in a proper manner since I'm not very familiar with mongoc's CMake setup. Is there to your knowledge a better way to achieve this than my current workaround? Would it be possible to get it fixed at your end so that I don't have to feel so dirty using objcopy?

Thanks!



 Comments   
Comment by Githook User [ 27/Feb/20 ]

Author:

{'username': 'rcsanchez97', 'name': 'Roberto C. Sánchez', 'email': 'roberto@connexer.com'}

Message: CDRIVER-3225 use COMMON_PREFIX pre-processor macro throughout
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/b7aa48780bf130fb62d662db681d5226eed9de93

Comment by Roberto Sanchez [ 25/Feb/20 ]

emanuel.birge, the two commits I just pushed address your first two concerns.

The symbol collisions have been fixed by prefixing them using the pre-processor, depending on which library they are being compiled for. PIC can be enabled for the static library components using a new option, as requested.

We have discussed your third concern internally and we are considering how to proceed. Keep in mind that the "1.0" in the name of libmongoc and libbson (and their associated CMake and pkg-config packages) is not the ABI version. The ABI of libmongoc and libbson has not been bumped from "0" in the history of either library, as neither has experienced an ABI-breaking change. It is not immediately clear that there would be much benefit from incrementing the minor or patch versions of the ABI. If there are specific use cases of which we should be aware that would benefit from more precise ABI versioning, please let us know.

Comment by Githook User [ 25/Feb/20 ]

Author:

{'username': 'rcsanchez97', 'name': 'Roberto C. Sánchez', 'email': 'roberto@connexer.com'}

Message: CDRIVER-3225 add CMake option for building static components with -fPIC
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/f023d3b9fe269bbf29ae813f014487df57230aca

Comment by Githook User [ 25/Feb/20 ]

Author:

{'username': 'rcsanchez97', 'name': 'Roberto C. Sánchez', 'email': 'roberto@connexer.com'}

Message: CDRIVER-3225 prevent collisions of common symbols
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/9097d9f1cb4c0f4ad45f27a419f6f633137ae7dd

Comment by Kevin Albertson [ 23/Jul/19 ]

Hi emanuel.birge, thank you for the detailed report! We will investigate this after our 1.15.0 release.

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