Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-3225

Static libraries produced by cmake builds on Linux cannot be used without modification

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.17.0-beta, 1.17.0
    • Affects Version/s: 1.14.0
    • Component/s: Build
    • None
    • Environment:
      Ubuntu 16.04/18.04, quite possibly Linux in general

      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!

            Assignee:
            roberto.sanchez@mongodb.com Roberto Sanchez
            Reporter:
            emanuel.birge Emanuel Birge
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: