LInk with/without LLVM_ENABLE_ABI_BREAKING_CHECKS

I want use clang sources in my project. Rrlease version is linked and running OK, but debug version need llvm/lib/Support/ABIBreak.cpp to link and has runtime errors. This errors I can avoid by modying HandleLLVMOptions.cmake by defining LLVM_ABI_BREAKING_CHECKS.
I can link debug objects and run OK, but it is huge: link need about 14 GB memory and takes 3 minutes of time.
It will be well - near all objects files compiled as release but some compiled as debug. This is main problem: after modyfuing cmake , release version need EnableABIBreakingChecks and has errors. How do mix world with enable check and disable check?

ABI breaking checks/no-checks can't be mixed. But you can turn off ABI
breaking checks while turning on debug info, so that the bits built
with debug info will be compatible with the bits built without debug
info. (or turn on ABI breaking checks while turning off debug info, I
guess)

Hi Andy, mixing LLVM_ABI_BREAKING_CHECKS objects and non-LLVM_ABI_BREAKING_CHECKS objects is not supported.
Please check out https://llvm.org/docs/ProgrammersManual.html#abi-breaking-checks

More specifically, Error in LLVM_ABI_BREAKING_CHECKS mode has one
additional bit field. If you pass `Error` compiled without
LLVM_ABI_BREAKING_CHECKS (the bit is not set) to an object with
LLVM_ABI_BREAKING_CHECKS (which checks whether the bit is set), it will assuredly lead to failures.
Other frequently used types, e.g. ilist and DenseMap will have similar failures.

LLVM Default:

  • LLVM_ABI_BREAKING_CHECKS was turn out
  • no problem release version
  • debug version compiled (about 1.5 hours) by ninja is also OK
  • but debug files .o from .a linked in my simple cmake, need DisableABIBreakingChecks and file llvm/lib/Support/ABIBreak.cpp
    After adding this file to cmake, is error in ArgList

Why sometimes is OK and not need link file llvm/lib/Support/ABIBreak.cpp and sometimes is error with linked this file (required EnableABIBreakingChecks or DisableABIBreakingChecks) In abi-breaking.h is:

namespace llvm {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
extern int EnableABIBreakingChecks;
LLVM_HIDDEN_VISIBILITY
__attribute__((weak)) int *VerifyEnableABIBreakingChecks =
    &EnableABIBreakingChecks;
#else
extern int DisableABIBreakingChecks;
LLVM_HIDDEN_VISIBILITY
__attribute__((weak)) int *VerifyDisableABIBreakingChecks =
    &DisableABIBreakingChecks;
#endif
}

Always is extern EnableABIBreakingChecks or DisableABIBreakingChecks, but if is OK, no need link ABIBreak.cpp.

The mechanism was introduced in https://reviews.llvm.org/D26876 . The
idea is that a translation unit including abi-breaking.h will get a
weak hidden variable referencing either EnableABIBreakingChecks or
DisableABIBreakingChecks. The definitions are weak so multiple
definitions are allowed. But the references are strong -> if
EnableABIBreakingChecks is referenced but not defined, it will be a
linker error.

However, this scheme can create many small input .data sections if
-Wl,--gc-sections or dead stripping is not enabled. More precisely, we
waste 1778 * 8 bytes for 'opt' in a non -Wl,--gc-sections build. On
ELF, we can use zero cost references (.reloc directives) but that can
make the code even uglier.

Why sometimes is OK and not need link file llvm/lib/Support/ABIBreak.cpp and sometimes is error with linked this file (required EnableABIBreakingChecks or DisableABIBreakingChecks) In abi-breaking.h is:

namespace llvm {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
extern int EnableABIBreakingChecks;
LLVM_HIDDEN_VISIBILITY
__attribute__((weak)) int *VerifyEnableABIBreakingChecks =
    &EnableABIBreakingChecks;
#else
extern int DisableABIBreakingChecks;
LLVM_HIDDEN_VISIBILITY
__attribute__((weak)) int *VerifyDisableABIBreakingChecks =
    &DisableABIBreakingChecks;
#endif
}

Always is extern EnableABIBreakingChecks or DisableABIBreakingChecks, but if is OK, no need link ABIBreak.cpp.

That's the purpose - you should not mix ABI breaking checks with
non-ABI breaking checks, they are invalid to combine.

In general, I believe that if you hit a missing symbol it means that you are building your client against a version of the LLVM header with the EnableABIBreakingChecks (respectively DisableABIBreakingChecks) and then try to link against a binary LLVM that was built with DisableABIBreakingChecks (or respectively EnableABIBreakingChecks).

If this is not the case, it’d be interesting to get more detailed information about what you’re doing exactly. Reproduction steps would be ideal :slight_smile: