0

Motivation: Some libraries, e.g. Eigen have ABI that depends on compiler switches.

Question: could users of this library somehow encode this behavior so that if you try to link components compiled with different compiler switches you get a linker error.

So if it is not clear why I am asking about:

Alice the library developer builds her (not header only library) with no special compiler flag and exposes Eigen in her API.

Bob the library consumer compiles with AVX2 enabled, he also uses Eigen in his code. He uses Alice library.

Bob gets crashes at runtime.

Can Alice prevent her library linking in Bob's application? Assume that Alice knows to detect ABI mismatch using preprocessor macros that affect Eigen ABI.

note: I am fine with using C++20 or C++23 solutions if implemented in compilers.

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • Bob is the one responsible here for ensuring binary compatibility of his executable with the libraries he is using. While Alice can put some interface checking code at library initialization it can't be 100% fault-proof. – user7860670 Dec 08 '21 at 10:11
  • Ah I think I see. You are looking for something that can just be placed in Alice's headers to ensure Bob is notified? – StoryTeller - Unslander Monica Dec 08 '21 at 10:12
  • @StoryTeller-UnslanderMonica maybe I should not have mentioned Eigen... Point is that Alice knows her library API depends on compiler switches. So if Bob uses alice.h with AVX2 and alice.lib is compiled without AVX2 then Alice knows there will be crashes. But can Alice prevent linking of alice.lib with Bob's code that includes alice.h but "sees" different ABI due to different compiler switches. – NoSenseEtAl Dec 08 '21 at 10:17
  • 1
    If the `alice.lib` has an init function I could imagine that it is possible to force a linking error by using template definition and specialization based on the macros. – t.niese Dec 08 '21 at 10:20
  • Library can't prevent such things without your help. In case we are talking about dynamic linking - the might be an error, if a symbol has not been found (during implicit loading). But if you are talking about linking done by a *linker* during your build - it might warn you or prevent from linking a code compiled with different flags – Sergey Kolesnik Dec 08 '21 at 10:25
  • @t.niese not familiar with that solution, do you have a link to existing answer of yours or someone elses that explains how that works? – NoSenseEtAl Dec 08 '21 at 10:25
  • 1
    related question: [How to make sure different C++ code base using the same macro?](https://stackoverflow.com/questions/45873920/how-to-make-sure-different-c-code-base-using-the-same-macro/45874331) – user7860670 Dec 08 '21 at 10:25
  • 1
    No, I don't have. But it is basically similar to what is suggested in the question shown by @user7860670. The idea for both is the same, you force a situation for which the linking fails because a declaration is missing or not matching if the macros change. – t.niese Dec 08 '21 at 10:29
  • @user7860670 I think it might be a duplicate... – NoSenseEtAl Dec 08 '21 at 10:30
  • @user7860670 I think it is fine to mark this Q as duplicate, thank you for that link – NoSenseEtAl Dec 08 '21 at 10:30
  • @NoSenseEtAl one note: you need to make sure that it is a function or a class that is guaranteed to be used in the code of the one using the `alice.lib`. That's why I mentioned the `init` function. – t.niese Dec 08 '21 at 10:37
  • @t.niese that sucks :) I was hoping for something that works regardless of what user does... even in case when beside include entire program is int main(){} – NoSenseEtAl Dec 08 '21 at 11:06
  • 1
    If the user does nothing with the library then no ABI problem exists :P And linking errors also only occur for those parts that are used. So if you have no guaranteed entry point into the library you would need to include that hack into everything the user utilized. This however could also be done using a static variable that is guaranteed to be initialized that does this check. – t.niese Dec 08 '21 at 13:23
  • MSVC has `#pragma detect_mismatch`. – T.C. Dec 08 '21 at 16:40
  • @T.C that sounds like a great feature, IDK why I never heard of it before, I you make it an answer I will upvote. – NoSenseEtAl Dec 08 '21 at 16:50

2 Answers2

1

For avx2 at least it looks like you can know if the compiler is compiling for it or not via built in defines. This probably won't help though since it sounds like you just get a binary of Alice's library.

Ideally I think Bob would just compile Alices library himself and then link to it guaranteeing compatible abi. Barring this option I can think of one less than ideal way of checking, objdump the library and grep for avx2 instructions in the disassembly to see if they are being used.

floomby
  • 191
  • 1
  • 9
0

C++ knows nothing about compiler switches/options. They are compiler specific and not formally specified (usually). So there's no way to encode it portable and generic way. You just won't know what you need to encode. There are some options if you limit the scope to a particular platform/compiler/toolset/option. But, again, it is out of C++ scope and more about tools. For example gcc/clang allow recording of command line options (-grecord-gcc-switches). By forcing library suppliers to use that and checking the records in pre-link step you might achieve what you want. Theoretically atleast....

ouflak
  • 2,458
  • 10
  • 44
  • 49