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.
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.
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.
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 ${library. pipeline-utils. version} in the SCM configuration somewhere."
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
libmysolib_version_<N>
, ordlopen(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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With