Crystal: Fails to build with LLVM 7

Created on 20 Sep 2018  路  32Comments  路  Source: crystal-lang/crystal

Compilation of Crystal with LLVM 7 fails:

Using /usr/bin/llvm-config [version=7.0.0]
g++ -c -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -pipe     -o src/llvm/ext/llvm_ext.o src/llvm/ext/llvm_ext.cc -I/usr/include -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -pipe -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wdelete-non-virtual-dtor -Wno-comment -ffunction-sections -fdata-sections -O3 -DNDEBUG  -fno-exceptions -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
src/llvm/ext/llvm_ext.cc:89:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateFunction(DIBuilderRef, LLVMMetadataRef, const char*, const char*, LLVMMetadataRef, unsigned int, LLVMMetadataRef, bool, bool, unsigned int, llvm::DINode::DIFlags, bool, LLVMValueRef)'
 LLVMMetadataRef LLVMDIBuilderCreateFunction(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:277:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateFunction(LLVMDIBuilderRef, LLVMMetadataRef, const char*, size_t, const char*, size_t, LLVMMetadataRef, unsigned int, LLVMMetadataRef, LLVMBool, LLVMBool, unsigned int, LLVMDIFlags, LLVMBool)'
 LLVMMetadataRef LLVMDIBuilderCreateFunction(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:109:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateLexicalBlock(DIBuilderRef, LLVMMetadataRef, LLVMMetadataRef, unsigned int, unsigned int)'
 LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(DIBuilderRef Dref,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:292:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef, LLVMMetadataRef, LLVMMetadataRef, unsigned int, unsigned int)'
 LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:118:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateBasicType(DIBuilderRef, const char*, uint64_t, uint64_t, unsigned int)'
 LLVMMetadataRef LLVMDIBuilderCreateBasicType(DIBuilderRef Dref,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:536:1: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef, const char*, size_t, uint64_t, LLVMDWARFTypeEncoding)'
 LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:130:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderGetOrCreateTypeArray(DIBuilderRef, LLVMOpaqueMetadata**, unsigned int)'
 LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(DIBuilderRef Dref,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:420:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef, LLVMOpaqueMetadata**, size_t)'
 LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Builder,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:139:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderGetOrCreateArray(DIBuilderRef, LLVMOpaqueMetadata**, unsigned int)'
 LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(DIBuilderRef Dref,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:929:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef, LLVMOpaqueMetadata**, size_t)'
 LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:148:1: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateSubroutineType(DIBuilderRef, LLVMMetadataRef, LLVMMetadataRef)'
 LLVMDIBuilderCreateSubroutineType(DIBuilderRef Dref, LLVMMetadataRef File,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:435:1: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef, LLVMMetadataRef, LLVMOpaqueMetadata**, unsigned int, LLVMDIFlags)'
 LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:154:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateAutoVariable(DIBuilderRef, LLVMMetadataRef, const char*, LLVMMetadataRef, unsigned int, LLVMMetadataRef, int, llvm::DINode::DIFlags, uint32_t)'
 LLVMMetadataRef LLVMDIBuilderCreateAutoVariable(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:1115:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateAutoVariable(LLVMDIBuilderRef, LLVMMetadataRef, const char*, size_t, LLVMMetadataRef, unsigned int, LLVMMetadataRef, LLVMBool, LLVMDIFlags, uint32_t)'
 LLVMMetadataRef LLVMDIBuilderCreateAutoVariable(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:176:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateParameterVariable(DIBuilderRef, LLVMMetadataRef, const char*, unsigned int, LLVMMetadataRef, unsigned int, LLVMMetadataRef, int, llvm::DINode::DIFlags)'
 LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:1133:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateParameterVariable(LLVMDIBuilderRef, LLVMMetadataRef, const char*, size_t, unsigned int, LLVMMetadataRef, unsigned int, LLVMMetadataRef, LLVMBool, LLVMDIFlags)'
 LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:192:14: error: conflicting declaration of C function 'LLVMOpaqueValue* LLVMDIBuilderInsertDeclareAtEnd(DIBuilderRef, LLVMValueRef, LLVMMetadataRef, LLVMMetadataRef, LLVMValueRef, LLVMBasicBlockRef)'
 LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(DIBuilderRef Dref,
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:1064:14: note: previous declaration 'LLVMOpaqueValue* LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef, LLVMValueRef, LLVMMetadataRef, LLVMMetadataRef, LLVMMetadataRef, LLVMBasicBlockRef)'
 LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:206:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateExpression(DIBuilderRef, int64_t*, size_t)'
 LLVMMetadataRef LLVMDIBuilderCreateExpression(DIBuilderRef Dref, int64_t *Addr,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:940:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateExpression(LLVMDIBuilderRef, int64_t*, size_t)'
 LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:211:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateEnumerationType(DIBuilderRef, LLVMMetadataRef, const char*, LLVMMetadataRef, unsigned int, uint64_t, uint64_t, LLVMMetadataRef, LLVMMetadataRef)'
 LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:455:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateEnumerationType(LLVMDIBuilderRef, LLVMMetadataRef, const char*, size_t, LLVMMetadataRef, unsigned int, uint64_t, uint32_t, LLVMOpaqueMetadata**, unsigned int, LLVMMetadataRef)'
 LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:230:1: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateStructType(DIBuilderRef, LLVMMetadataRef, const char*, LLVMMetadataRef, unsigned int, uint64_t, uint64_t, llvm::DINode::DIFlags, LLVMMetadataRef, LLVMMetadataRef)'
 LLVMDIBuilderCreateStructType(DIBuilderRef Dref,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:573:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateStructType(LLVMDIBuilderRef, LLVMMetadataRef, const char*, size_t, LLVMMetadataRef, unsigned int, uint64_t, uint32_t, LLVMDIFlags, LLVMMetadataRef, LLVMOpaqueMetadata**, unsigned int, unsigned int, LLVMMetadataRef, const char*, size_t)'
 LLVMMetadataRef LLVMDIBuilderCreateStructType(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:252:1: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateReplaceableCompositeType(DIBuilderRef, LLVMMetadataRef, const char*, LLVMMetadataRef, unsigned int)'
 LLVMDIBuilderCreateReplaceableCompositeType(DIBuilderRef Dref,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:793:1: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateReplaceableCompositeType(LLVMDIBuilderRef, unsigned int, const char*, size_t, LLVMMetadataRef, LLVMMetadataRef, unsigned int, unsigned int, uint64_t, uint32_t, LLVMDIFlags, const char*, size_t)'
 LLVMDIBuilderCreateReplaceableCompositeType(
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:279:1: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreateMemberType(DIBuilderRef, LLVMMetadataRef, const char*, LLVMMetadataRef, unsigned int, uint64_t, uint64_t, uint64_t, llvm::DINode::DIFlags, LLVMMetadataRef)'
 LLVMDIBuilderCreateMemberType(DIBuilderRef Dref, LLVMMetadataRef Scope,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:595:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreateMemberType(LLVMDIBuilderRef, LLVMMetadataRef, const char*, size_t, LLVMMetadataRef, unsigned int, uint64_t, uint32_t, uint64_t, LLVMDIFlags, LLVMMetadataRef)'
 LLVMMetadataRef LLVMDIBuilderCreateMemberType(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:295:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMDIBuilderCreatePointerType(DIBuilderRef, LLVMMetadataRef, uint64_t, uint64_t, const char*)'
 LLVMMetadataRef LLVMDIBuilderCreatePointerType(DIBuilderRef Dref,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:550:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef, LLVMMetadataRef, uint64_t, uint32_t, unsigned int, const char*, size_t)'
 LLVMMetadataRef LLVMDIBuilderCreatePointerType(
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc:309:17: error: conflicting declaration of C function 'LLVMOpaqueMetadata* LLVMTemporaryMDNode(LLVMContextRef, LLVMOpaqueMetadata**, unsigned int)'
 LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs,
                 ^~~~~~~~~~~~~~~~~~~
In file included from src/llvm/ext/llvm_ext.cc:24:
/usr/include/llvm-c/DebugInfo.h:991:17: note: previous declaration 'LLVMOpaqueMetadata* LLVMTemporaryMDNode(LLVMContextRef, LLVMOpaqueMetadata**, size_t)'
 LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef Ctx, LLVMMetadataRef *Data,
                 ^~~~~~~~~~~~~~~~~~~
src/llvm/ext/llvm_ext.cc: In function 'void LLVMWriteBitcodeWithSummaryToFile(LLVMModuleRef, const char*)':
src/llvm/ext/llvm_ext.cc:443:28: error: invalid initialization of reference of type 'const llvm::Module&' from expression of type 'llvm::Module*'
   llvm::WriteBitcodeToFile(m, OS, true, &moduleSummaryIndex, true);
                            ^
In file included from src/llvm/ext/llvm_ext.cc:28:
/usr/include/llvm/Bitcode/BitcodeWriter.h:129:8: note: in passing argument 1 of 'void llvm::WriteBitcodeToFile(const llvm::Module&, llvm::raw_ostream&, bool, const llvm::ModuleSummaryIndex*, bool, llvm::ModuleHash*)'
   void WriteBitcodeToFile(const Module &M, raw_ostream &Out,
        ^~~~~~~~~~~~~~~~~~
make: *** [Makefile:125: src/llvm/ext/llvm_ext.o] Error 1
feature compiler

Most helpful comment

Is there an update on this?

All 32 comments

Unfortunately my above commit is insufficient; it seems the builtins @llvm.memcpy @llvm.memmove @llvm.memset need tweaking too. 馃

Thanks for taking care of this.

@foutrelis are you working on fixing the support for LLVM 7.0? It will come handy for the next release. But if not, let us know.

I poked around a bit more but I feel someone more experienced needs to handle this so it gets fixed properly.

I took a peek at this, it looks like these lines needs to be changed since align is now specified by parameter attribute. However, I'm new to both Crystal and LLVM, so I'm not totally sure how to change this.

@foutrelis thanks for trying to fix the LLVM7 integration! Could you open a pull request woth your initial fix? Ultimately we shall move to the official DIBuilder C API (it's finally coming) but as a quick fix this will do the job.

For the LLVM intrinsics, just the symbols were changed, if I understood correctly. The names are now generic (e.g. llvm.memcpy) instead of having distinct symbols for the different integer sizes (e.g. llvm.memcpy.p0i8.p0i8.i64). The patch is about checking for LLVM version and use old symbols with older releases (4, 5, 6) and the new, generic, symbols for new releases.

@ysbaddaden i think the names are the same, it's just the align parameter to the intrinsics which have changed. They're now specified like this: https://llvm.org/docs/LangRef.html#attr-align.

Yes, you're right.

  • the easy part: we used to pass align: 0 which means that we don't care about the parameter, and can just skip it;
  • the complex part: the definitions in crystal are in src/intrinsics.cr but they depend on the LLVM version the compiler was compiled against (not LibLLVM::VERSION for example) so we need a macro method to return the linked LLVM version (for example), so we can pick the right definitions for the program that is being compiled...

@ysbaddaden perhaps make the memset/memcpy/memmove just be compiler intrinsics and handle all the logic inside the standard compiler def memcpy which we already have to make work - and LibLLVM::VERSION is present there.

This is what I've tried so far: https://github.com/foutrelis/crystal/commits/llvm7

The first two commits (adding LibLLVM::GE_* constants and renaming conflicting functions) should be OK. The last commit that tries to fix mem{move,cpy,set} is a shot in the dark and I was unable to get it to work.

Building the above with Crystal compiled against LLVM 6 (but llvm-config pointing to LLVM 7) will produce errors such as these:

Module validation failed: Intrinsic has incorrect argument type!
void (i8*, i8*, i64, i1)* @llvm.memcpy.p0i8.p0i8.i64
Intrinsic has incorrect argument type!
void (i8*, i8*, i64, i1)* @llvm.memcpy.p0i8.p0i8.i64
Intrinsic has incorrect argument type!
void (i8*, i8, i64, i1)* @llvm.memset.p0i8.i64

Building with Crystal compiled against LLVM 6 with module verification disabled will show linking errors:

/usr/bin/ld: _main.o: in function `__crystal_main':
main_module:(.text+0x300): undefined reference to `llvm.memset.p0i8.i64'
/usr/bin/ld: main_module:(.text+0xbb4): undefined reference to `llvm.memset.p0i8.i64'
...
Error: execution of command failed with code: 1: `cc "${@}" -o '/tmp/crystal/home-foutrelis-desktop-crystal-trunk-src-crystal-0.26.1-src-ecr-process.cr/macro_run'  -rdynamic  -lpcre -lgc -lpthread /home/foutrelis/desktop/crystal/trunk/src/crystal-0.26.1/src/ext/libcrystal.a -levent -lrt `/usr/bin/llvm-config --libs --system-libs --ldflags 2> /dev/null` -lstdc++ -ldl -L/usr/lib -L/usr/local/lib`
make: *** [Makefile:124: .build/crystal] Error 1

Obviously, feel free to cherry-pick the first two commits if they seem OK to you. You can probably ignore the last one and implement a (much) better approach from scratch.

@foutrelis yes, that's because the llvm intrinsic to use is the one for the llvm version the compiler binary is compiled with (must be hardcoded), not the llvm version we're building crystal against (accessible in macros). @RX14 proposal is good, it's merely using @[Primitive(:llvm_memcpy)] then implement this in src/compiler/crystal/codegen/primitives.cr and select there the old/new definition based on the LLVM version, but interacting/manipulating the AST is beyond my knowledge of the compiler internals...

I took a similar approach in https://github.com/bcardiff/crystal/tree/llvm7 and of course got stuck with the duality of running against one llvm and linking to another one.

I would prefer to avoid adding primitives as much as possible.

for osx developers using brew the compile flags might need to be tweaked to build and run with different llvm. But since the release process uses a shipped llvm version, the next release might work. I still need to check if that will be possible.

Is there an update on this?

I made it compile a while ago in a branch but it just segfaults somewhere deep in llvm and I gave up. If someone could make that work it'd be great.

@RX14 if it segfaults you might want to try using a debug build from LLVM, they usually have lots of asserts and that way you can know where the problem is. Alternatively, you can run it through gbd or lldb and it will show the stack trace. (but I understand this whole process is painful because I experienced it too ^_^)

@asterite I did that, I found the assert message where it was segfaulting, but I didn't copy down what the assert message was and I didn't have the time to debug it.

We also discussed about implementing the breaking changes (https://github.com/crystal-lang/crystal/issues/6754#issuecomment-423399150) as primitives.

We don't need to, my patch works well without primitives but it would probably be cleaner with primitives.

I did some investigation and got the latest master branch to compile and found that crystal specs segfault on expect_raises. I tried out some specs on a personal project and the only ones that failed were those that use Minitest's assert_raises

Hi, are there any plans to support newer versions of LLVM going forward?

Context: OpenBSD is moving to LLVM 8 in the next release. There are no back ports of older versions.

There are plans. The idea is to bump the llvm we are using in the CI and support the newer versions of llvm. Whether it will fit in 0.30 or not it depends on how fast my current tasks go.

Of course, anyone is able to keep iterating on the latest efforts the input will be welcomed.

If someone can review the expect raise issue, that would be great...

Note that LLVM 7 and LLVM 8 now bring most of what we manually maintain in llvm ext (DIBuilder, Atomic) and we could drop most (if not all) of the custom C++ functions in a near future :-)

I鈥檓 not sure we will be able to drop llvm-4.0 soon. Doing that will force old distro users to use a custom llvm build. Plus we would be cutting the possibility of native package with dependency to the native llvm package of each distro.

But dropping 3.x for good will clean plenty of things still.

Doing that will force old distro users to use a custom llvm build

Do distros with an over 2 year old LLVM still update Crystal? My impression is that they don't do that, but I don't know crystal too well.

That's definitely conditional on whether the goal is to aid distros in building crystal, or aid users in building their own.

But most users probably do not want to build their own, they want to download prebuilt compilers from repos which are often provided at https://dist.crystal-lang.org (because it doesn't seem like many distros package crystal yet), or even via a tarball on the crystal releases page.

As for distros: any distro that has an llvm version which is that old is not a rolling release, which means they will have policies about when it's okay to update to a new feature release. The policies inevitably boil down to "under no circumstances ever". For example, even though Debian does not ship a crystal package, if they did they could usually only update to new feature releases in Debian sid, now that buster was just released and entered full feature freeze.

Even Debian stretch, FWIW, has llvm 5 & 6 in the backports repository. You'll need to go back to jessie to find a Debian release purely limited to llvm <= 4.

Let's not get sidetracked: the issue of supporting LLVM 7 and 8 is a technical one, one which ended in segfaults inside LLVM last time i tried. Lets get that solved first and debate dropping support for old version in a later issue.

I've updated https://github.com/bcardiff/crystal/tree/llvm7
I was trying to make things work against 7.0.1 in osx

  • I switched to Crystal::LLVM_VERSION in src/intrinsics.cr to compare with the llvm version the compiler is built.
  • I needed to rework IS_LT_70 definition (not 100% why)
  • Trying to set the alignment arguments (which are nice to have but not mandatory AFAIK) generates a (isa<X>(Val) && "cast<Ty>() argument of incompatible type!")

I experienced something similar to @wmoxam https://github.com/crystal-lang/crystal/issues/6754#issuecomment-462181708. The underlying issue is that LibUnwind.raise_exception(unwind_ex) in __crystal_raise is not raising when compiling the program against llvm-7. There seems to be some issue there, searching "llvm7 libunwind" shows some results of issues. But I wasn't able to make head and tails from them.

@wmoxam I didn't need https://github.com/wmoxam/crystal/commit/7a945c2cd02caf2b86a3c125cfcd712e17550ed9 since from the commits linked in the message those should be backward compatible. But good information!

After this, I tried to upgrade directly to llvm8 in case the libunwind worked there. But after fixing some changes in the DI interface in https://github.com/bcardiff/crystal/commit/45e1533ba938e1b0e61645c5a341435ea6f6d7c0 I got Assertion failed: (!N->isTemporary() && "Expected all forward declarations to be resolved"), function resolveCycles, file .../llvm-8.0.0.src/lib/IR/Metadata.cpp, line 635.

So, still not there, but the code is rebased in master and the issue is for llvm-7 is narrowed to libunwind. Hopefully, there is some information I am missing that will make this move forward.

WSL Ubuntu 16 failing to build with LLVM7 on master 3b2bde6
https://gist.github.com/Daniel-Worrall/14dca4fe30fcbfec5c1cb7d6d70f0530

@Daniel-Worrall Did you try to do what the error message suggests?

/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.

Exhaustion got the better of me and I compiled on LLVM7

Was this page helpful?
0 / 5 - 0 ratings