Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce linking with a shared library with -Wl,--as-needed (when only templates are provided)

I am creating a template-only C++ library. However, I'd like to provide an 'empty' shared library as well, so that through controlling SONAME I would be able to enforce rebuilds of the template consumers whenever the templates change in a way resulting in instantiated template ABI incompatibility.

Sadly, if a particular user has -Wl,--as-needed in his LDFLAGS, the linker is going to remove my shared library from NEEDED because the compiled executable is not requesting any symbols from it. How can I ensure that the program will always be linked against my library, preferably not introducing unnecessary dummy function calls (or if I have to, making them least burdening)?

Edit: as a note, the particular template class provides static methods, and usually only those static methods are used. Thus, it is not a good idea to rely on anything put in the constructor, and I'd really like to avoid burdening all the methods with some kind of enforcement.


Inspired by @EmployedRussian, I achieved:

extern int dummy;

namespace
{
    struct G
    {
        inline G()
        {
            dummy = 0;
        }
    };

    static const G g;
}

But sadly, that performs the assignment once for every unit including the header file.

like image 361
Michał Górny Avatar asked Aug 11 '12 19:08

Michał Górny


People also ask

What is a Jenkins shared library and how it is useful?

What Is a Shared Library in Jenkins? A shared library in Jenkins is a collection of Groovy scripts shared between different Jenkins jobs. To run the scripts, they are pulled into a Jenkinsfile. Each shared library requires users to define a name and a method of retrieving source code.

How do you call a shared library in Jenkins?

Create a separate git repo for the Jenkins pipeline library & push the shared library code to that repo. Integrate the shared library repo in Jenkins under the Manage Jenkins section. Create Jenkinsfile in the project. In that Jenkinsfile, Import & use the shared library.

How shared libraries work in Linux?

Shared libraries are the most common way to manage dependencies on Linux systems. These shared resources are loaded into memory before the application starts, and when several processes require the same library, it will be loaded only once on the system. This feature saves on memory usage by the application.

When using legacy SCM you will need to include?

"When using Legacy SCM, you will need to include ${library. pipeline-utils. version} in the SCM configuration somewhere."


2 Answers

However, I'd like to provide an 'empty' shared library as well, so that through controlling SONAME I would be able to enforce rebuilds of the template consumers whenever the templates change in a way resulting in instantiated template ABI incompatibility.

This will force an error at runtime.

You can trivially achieve the same result (runtime error) without using SONAME. In one of your template headers, put in a global object that will at runime

  1. Take address of or call libmysolib_version_<N>, or
  2. Do dlopen(libmysolib.so, ...) and dlsym("libmysolib_version_<N>", ...)

Then just keep incrementing N every time you break the ABI.

preferably not introducing unnecessary dummy function calls

Taking address of libmysolib_version_<N> does not call a function; it just forces the runtime linker to find that symbol once (at startup). You may though run afoul of the linker garbage collection.

like image 73
Employed Russian Avatar answered Nov 11 '22 23:11

Employed Russian


I'd recommend an alternative approach:

myheader.h 

namespace mylib_1 {
   void foo(); 
   //all the code goes there
}
namespace mylib = mylib_1;

User calls:

mylib::foo()

The code that uses different myheader version would not link as it would change the signature of the functions.

This approach is used by ICU

like image 35
Artyom Avatar answered Nov 12 '22 01:11

Artyom