Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dependency on LLD, wrap it into Python #419

Closed
wants to merge 25 commits into from
Closed

Conversation

certik
Copy link
Contributor

@certik certik commented Nov 14, 2018

Adds LLD as a dependency, and wraps it into Python. This allows llvmlite to compile to executables, without any external dependencies such as ld or gcc.

TODO:

  • Make all Travis tests pass, test LLD on 64bit linux
  • Write a test for 32 bits linux? Currently only 64 bits are tested.
  • Get it to compile on macOS
  • Get it to compile on Windows
  • Get the PyPy test working
  • Implement LLD for macOS and test it
  • Implement LLD for Windows and test it
  • Squash commits into a nice set of patches

Fixes #311.

@certik
Copy link
Contributor Author

certik commented Nov 14, 2018

On my machine the llvmdev package builds, but lld fails with:

$ cd conda-recipes/lld
$ conda build .
...
[ 99%] Building CXX object tools/lld/CMakeFiles/lld.dir/lld.cpp.o
[100%] Linking CXX executable ../../bin/lld
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCOFF.a(MapFile.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJmmmEEE[_ZTIN4llvm13format_objectIJmmmEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCOFF.a(PDB.cpp.o):(.data.rel.ro._ZTIN4llvm8codeview27DebugChecksumsSubsectionRefE[_ZTIN4llvm8codeview27DebugChecksumsSubsectionRefE]+0x10): undefined reference to `typeinfo for llvm::codeview::DebugSubsectionRef'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCOFF.a(PDB.cpp.o):(.data.rel.ro._ZTIN4llvm8codeview29DebugStringTableSubsectionRefE[_ZTIN4llvm8codeview29DebugStringTableSubsectionRefE]+0x10): undefined reference to `typeinfo for llvm::codeview::DebugSubsectionRef'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldDriver.a(DarwinLdDriver.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJyEEE[_ZTIN4llvm13format_objectIJyEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldDriver.a(DarwinLdDriver.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJtEEE[_ZTIN4llvm13format_objectIJtEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldELF.a(MapFile.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJimimmEEE[_ZTIN4llvm13format_objectIJimimmEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldMachO.a(MachONormalizedFileToAtoms.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJPKN3lld4AtomEEEE[_ZTIN4llvm13format_objectIJPKN3lld4AtomEEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldYAML.a(ReaderWriterYAML.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJttEEE[_ZTIN4llvm13format_objectIJttEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCore.a(Resolver.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJPN3lld13UndefinedAtomEEEE[_ZTIN4llvm13format_objectIJPN3lld13UndefinedAtomEEEE]+0x10): more undefined references to `typeinfo for llvm::format_object_base' follow
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCore.a(Error.cpp.o):(.data.rel.ro._ZTIN4llvm9ErrorInfoIN3lld12GenericErrorENS_13ErrorInfoBaseEEE[_ZTIN4llvm9ErrorInfoIN3lld12GenericErrorENS_13ErrorInfoBaseEEE]+0x10): undefined reference to `typeinfo for llvm::ErrorInfoBase'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_15MCTargetOptions18AsmInstrumentationEEE[_ZTIN4llvm2cl15OptionValueCopyINS_15MCTargetOptions18AsmInstrumentationEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_15MCTargetOptions18AsmInstrumentationEEE[_ZTIN4llvm2cl6parserINS_15MCTargetOptions18AsmInstrumentationEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_15MCTargetOptions18AsmInstrumentationELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_15MCTargetOptions18AsmInstrumentationELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_5Reloc5ModelEEE[_ZTIN4llvm2cl15OptionValueCopyINS_5Reloc5ModelEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_5Reloc5ModelEEE[_ZTIN4llvm2cl6parserINS_5Reloc5ModelEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_5Reloc5ModelELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_5Reloc5ModelELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_11ThreadModel5ModelEEE[_ZTIN4llvm2cl15OptionValueCopyINS_11ThreadModel5ModelEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_11ThreadModel5ModelEEE[_ZTIN4llvm2cl6parserINS_11ThreadModel5ModelEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_11ThreadModel5ModelELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_11ThreadModel5ModelELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_9CodeModel5ModelEEE[_ZTIN4llvm2cl15OptionValueCopyINS_9CodeModel5ModelEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_9CodeModel5ModelEEE[_ZTIN4llvm2cl6parserINS_9CodeModel5ModelEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_9CodeModel5ModelELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_9CodeModel5ModelELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_17ExceptionHandlingEEE[_ZTIN4llvm2cl15OptionValueCopyINS_17ExceptionHandlingEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_17ExceptionHandlingEEE[_ZTIN4llvm2cl6parserINS_17ExceptionHandlingEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_17ExceptionHandlingELb0ENS0_6parserIS2_EEEE[_ZTIN4llvm2cl3optINS_17ExceptionHandlingELb0ENS0_6parserIS2_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_13TargetMachine15CodeGenFileTypeEEE[_ZTIN4llvm2cl15OptionValueCopyINS_13TargetMachine15CodeGenFileTypeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_13TargetMachine15CodeGenFileTypeEEE[_ZTIN4llvm2cl6parserINS_13TargetMachine15CodeGenFileTypeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_13TargetMachine15CodeGenFileTypeELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_13TargetMachine15CodeGenFileTypeELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_10FPDenormal12DenormalModeEEE[_ZTIN4llvm2cl15OptionValueCopyINS_10FPDenormal12DenormalModeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_10FPDenormal12DenormalModeEEE[_ZTIN4llvm2cl6parserINS_10FPDenormal12DenormalModeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_10FPDenormal12DenormalModeELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_10FPDenormal12DenormalModeELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_8FloatABI7ABITypeEEE[_ZTIN4llvm2cl15OptionValueCopyINS_8FloatABI7ABITypeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_8FloatABI7ABITypeEEE[_ZTIN4llvm2cl6parserINS_8FloatABI7ABITypeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_8FloatABI7ABITypeELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_8FloatABI7ABITypeELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_10FPOpFusion14FPOpFusionModeEEE[_ZTIN4llvm2cl15OptionValueCopyINS_10FPOpFusion14FPOpFusionModeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_10FPOpFusion14FPOpFusionModeEEE[_ZTIN4llvm2cl6parserINS_10FPOpFusion14FPOpFusionModeEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_10FPOpFusion14FPOpFusionModeELb0ENS0_6parserIS3_EEEE[_ZTIN4llvm2cl3optINS_10FPOpFusion14FPOpFusionModeELb0ENS0_6parserIS3_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_4EABIEEE[_ZTIN4llvm2cl15OptionValueCopyINS_4EABIEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_4EABIEEE[_ZTIN4llvm2cl6parserINS_4EABIEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_4EABIELb0ENS0_6parserIS2_EEEE[_ZTIN4llvm2cl3optINS_4EABIELb0ENS0_6parserIS2_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl15OptionValueCopyINS_12DebuggerKindEEE[_ZTIN4llvm2cl15OptionValueCopyINS_12DebuggerKindEEE]+0x10): undefined reference to `typeinfo for llvm::cl::GenericOptionValue'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl6parserINS_12DebuggerKindEEE[_ZTIN4llvm2cl6parserINS_12DebuggerKindEEE]+0x10): undefined reference to `typeinfo for llvm::cl::generic_parser_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldCommon.a(TargetOptionsCommandFlags.cpp.o):(.data.rel.ro._ZTIN4llvm2cl3optINS_12DebuggerKindELb0ENS0_6parserIS2_EEEE[_ZTIN4llvm2cl3optINS_12DebuggerKindELb0ENS0_6parserIS2_EEEE]+0x18): undefined reference to `typeinfo for llvm::cl::Option'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldWasm.a(WriterUtils.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJmEEE[_ZTIN4llvm13format_objectIJmEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldMachO.a(MachONormalizedFileYAML.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJjEEE[_ZTIN4llvm13format_objectIJjEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldMachO.a(MachONormalizedFileYAML.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJjjEEE[_ZTIN4llvm13format_objectIJjjEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/_build_env/bin/../lib/gcc/x86_64-conda_cos6-linux-gnu/7.3.0/../../../../x86_64-conda_cos6-linux-gnu/bin/ld: ../../lib/liblldReaderWriter.a(FileArchive.cpp.o):(.data.rel.ro._ZTIN4llvm13format_objectIJPKcEEE[_ZTIN4llvm13format_objectIJPKcEEE]+0x10): undefined reference to `typeinfo for llvm::format_object_base'
collect2: error: ld returned 1 exit status
tools/lld/CMakeFiles/lld.dir/build.make:138: recipe for target 'bin/lld' failed
make[2]: *** [bin/lld] Error 1
CMakeFiles/Makefile2:557: recipe for target 'tools/lld/CMakeFiles/lld.dir/all' failed
make[1]: *** [tools/lld/CMakeFiles/lld.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2
Traceback (most recent call last):
  File "/home/certik/ext/miniconda3/envs/build/bin/conda-build", line 11, in <module>
    sys.exit(main())
  File "/home/certik/ext/miniconda3/envs/build/lib/python3.7/site-packages/conda_build/cli/main_build.py", line 439, in main
    execute(sys.argv[1:])
  File "/home/certik/ext/miniconda3/envs/build/lib/python3.7/site-packages/conda_build/cli/main_build.py", line 430, in execute
    verify=args.verify, variants=args.variants)
  File "/home/certik/ext/miniconda3/envs/build/lib/python3.7/site-packages/conda_build/api.py", line 201, in build
    notest=notest, need_source_download=need_source_download, variants=variants)
  File "/home/certik/ext/miniconda3/envs/build/lib/python3.7/site-packages/conda_build/build.py", line 2275, in build_tree
    notest=notest,
  File "/home/certik/ext/miniconda3/envs/build/lib/python3.7/site-packages/conda_build/build.py", line 1500, in build
    utils.check_call_env(cmd, env=env, cwd=src_dir, stats=build_stats)
  File "/home/certik/ext/miniconda3/envs/build/lib/python3.7/site-packages/conda_build/utils.py", line 319, in check_call_env
    return _func_defaulting_env_to_os_environ('call', *popenargs, **kwargs)
  File "/home/certik/ext/miniconda3/envs/build/lib/python3.7/site-packages/conda_build/utils.py", line 299, in _func_defaulting_env_to_os_environ
    raise subprocess.CalledProcessError(proc.returncode, _args)
subprocess.CalledProcessError: Command '['/bin/bash', '-e', '/home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/work/conda_build.sh']' returned non-zero exit status 2.

@seibert
Copy link
Contributor

seibert commented Nov 14, 2018

Not 100% certain here, but a quick scan of the recipes indicates that the difference is likely due to conda-forge building LLVM with RTTI enabled, and our LLVM recipe building with RTTI disabled. I don't know the history of why we disabled RTTI, except perhaps we didn't need it and we thought it would make the final library smaller.

@certik
Copy link
Contributor Author

certik commented Nov 14, 2018

@seibert you are right, I just independently discovered that. LLD now builds.

Now I am figuring out how to wrap it, llvmlite style.

@certik
Copy link
Contributor Author

certik commented Nov 14, 2018

Now it fails during tests in llvmlite:

OSError: /home/certik/ext/miniconda3/envs/build/conda-bld/llvmlite_1542239134179/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla/lib/python3.7/site-packages/llvmlite/binding/libllvmlite.so: undefined symbol: _ZN3lld3elf4linkEN4llvm8ArrayRefIPKcEEbRNS1_11raw_ostreamE

I think that's probably because I don't link the lld libraries yet.

@certik
Copy link
Contributor Author

certik commented Nov 15, 2018

Still fails with the same error.

@certik
Copy link
Contributor Author

certik commented Nov 15, 2018

That missing symbols is in the liblldELF.a library:

$ nm /home/certik/ext/miniconda3/envs/build/conda-bld/lld_1542237425154/work/build/lib/liblldELF.a | grep _ZN3lld3elf4linkEN4llvm8ArrayRefIPKcEEbRNS1_11raw_ostreamE
0000000000000000 T _ZN3lld3elf4linkEN4llvm8ArrayRefIPKcEEbRNS1_11raw_ostreamE

@certik
Copy link
Contributor Author

certik commented Nov 15, 2018

Weird. When I compile it as follows:

conda create -n build_llvmlite -c /home/certik/ext/miniconda3/envs/build/conda-bld/ ca-certificates certifi icu libedit libffi libgcc-ng libstdcxx-ng libxml2 ncurses openssl pip python readline setuptools sqlite tk wheel xz zlib binutils_impl_linux-64 binutils_linux-64 gcc_impl_linux-64 gcc_linux-64 gxx_impl_linux-64 gxx_linux-64 libgcc-ng libstdcxx-ng make lld llvmdev
conda activate build_llvmlite
cd ffi
python build.py

and check the libllvmlite.so library, then the symbol is there:

$ nm libllvmlite.so | grep _ZN3lld3elf4linkEN4llvm8ArrayRefIPKcEEbRNS1_11raw_ostreamE
00000000017d4a00 t _ZN3lld3elf4linkEN4llvm8ArrayRefIPKcEEbRNS1_11raw_ostreamE

But if I build it using conda build, then the symbol is not there:

$ nm /home/certik/ext/miniconda3/envs/build/conda-bld/llvmlite_1542239900275/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla/lib/python3.7/site-packages/llvmlite/binding/libllvmlite.so | grep _ZN3lld3elf4linkEN4llvm8ArrayRefIPKcEEbRNS1_11raw_ostreamE
                 U _ZN3lld3elf4linkEN4llvm8ArrayRefIPKcEEbRNS1_11raw_ostreamE

So that's probably something with using different compilers somehow?

@certik
Copy link
Contributor Author

certik commented Nov 15, 2018

I didn't realize that I had to clean my working directory. So I did git clean -dfx. Now I get a different error on conda build

======================================================================
ERROR: test_imports (llvmlite.tests.test_llvmpy.TestMisc)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/certik/ext/miniconda3/envs/build/conda-bld/llvmlite_1542241506057/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla/lib/python3.7/site-packages/llvmlite/binding/ffi.py", line 120, in <module>
    lib = ctypes.CDLL(os.path.join(_lib_dir, _lib_name))
  File "/home/certik/ext/miniconda3/envs/build/conda-bld/llvmlite_1542241506057/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla/lib/python3.7/ctypes/__init__.py", line 356, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: /home/certik/ext/miniconda3/envs/build/conda-bld/llvmlite_1542241506057/_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_pla/lib/python3.7/site-packages/llvmlite/binding/libllvmlite.so: undefined symbol: _ZN4llvm15itaniumDemangleEPKcPcPmPi

@certik
Copy link
Contributor Author

certik commented Nov 15, 2018

The last commit fixes it. The undefined symbol was in the lld libraries, and it was defined in the LLVM libraries, so I just had to put the lld libraries before LLVM libraries on the linker line.

The llvmlite package now builds and tests run. Regarding the size, it increased from 16M to 17M, but I don't know if that's it, or if it will increase further once we actually put the Python wrappers in. So far I am only linking the C++ function that uses lld into the shared library.

@certik
Copy link
Contributor Author

certik commented Nov 15, 2018

I think it works:

$ conda build conda-recipes/llvmlite/
$ conda create -n test -c /home/certik/ext/miniconda3/envs/build/conda-bld/linux-64/ llvmlite
$ conda activate test
$ python
Python 3.7.1 (default, Oct 23 2018, 19:19:42) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import llvmlite.binding.initfini
>>> llvmlite.binding.initfini.lld_main_help()
OVERVIEW: lld

USAGE: ld.lld [options] <inputs>

OPTIONS:
  --allow-multiple-definition
                          Allow multiple definitions
  --as-needed             Only set DT_NEEDED for shared libraries if used
  --auxiliary <value>     Set DT_AUXILIARY field to the specified name
  --Bdynamic              Link against shared libraries
  --Bshareable            Build a shared object
  --Bstatic               Do not link against shared libraries
...
>>>

And the LLD program gets loaded and help displayed.

The size of the llvmlite tarball is 17 MB.

So this is a good start. Now we just need to expose the general arguments (list of strings) of lld_main() into Python and see if it actually links properly and creates an executable.

@certik certik changed the title WIP: Add dependency on LLD Add dependency on LLD Nov 16, 2018
@certik certik changed the title Add dependency on LLD Add dependency on LLD, wrap it into Python Nov 16, 2018
@certik
Copy link
Contributor Author

certik commented Nov 16, 2018

@seibert it works. Here is an example how to use llvmlite to produce an executable:

from llvmlite.binding import lld_main
lld_main(["ld.lld", "-o", "a.out", "print_01.o",
    "/usr/lib/x86_64-linux-musl/crt1.o", "/usr/lib/x86_64-linux-musl/libc.a"])

and the executable works:

$ ./a.out 
25 1 3 25 50 

This example uses print_01.o produced by llvmlite that implements a main() function that prints something on a screen using a printf() function. It requires libc, so I use the musl libc library. One has to link in the crt1.o stub that implements the _start symbol (that linux kernel executes), which initializes libc and starts the main function implemented in print_01.o.


Can you please help me get the PR in a state that can be merged? I don't know what design you want to have in llvmlite, so this PR implements a prototype that works, and now I am waiting for your feedback to tell me how you want things arranged and how to make this robust.

Regarding the size of the llvmlite package, as mentioned above, it is 17MB:

$ ll -h /home/certik/ext/miniconda3/envs/build/conda-bld/linux-64/llvmlite-0.21.0.dev-py37hf484d3e_219.tar.bz2
-rw-r--r-- 1 certik certik 17M Nov 16 12:43 /home/certik/ext/miniconda3/envs/build/conda-bld/linux-64/llvmlite-0.21.0.dev-py37hf484d3e_219.tar.bz2

So I think that didn't add any significant increase in size and given that llvmlite can now be used to produce executables, I think this is a big deal.

@seibert
Copy link
Contributor

seibert commented Nov 16, 2018

This is great! I've tagged @stuartarchibald to take a look at this next week, as the rest of the Numba developers are in the US and will be on holiday.

@coveralls
Copy link

coveralls commented Nov 17, 2018

Coverage Status

Coverage decreased (-0.02%) to 93.746% when pulling 42be9e4 on certik:lld into 5be6c73 on numba:master.

@certik
Copy link
Contributor Author

certik commented Nov 17, 2018

I installed the llvmdev and lld packages from this PR into the certik channel, and Travis now passes on Linux (https://travis-ci.org/numba/llvmlite/builds/456194499) for all Python versions. Could you please add the lld package into the numba channel for Linux, Mac and Windows? Then I can make sure tests pass on Mac and Windows also.

@codecov-io
Copy link

codecov-io commented Nov 18, 2018

Codecov Report

❗ No coverage uploaded for pull request base (master@ef9be78). Click here to learn what that means.
The diff coverage is 88.23%.

@@            Coverage Diff            @@
##             master     #419   +/-   ##
=========================================
  Coverage          ?   92.27%           
=========================================
  Files             ?       33           
  Lines             ?     5194           
  Branches          ?      363           
=========================================
  Hits              ?     4793           
  Misses            ?      323           
  Partials          ?       78

@certik
Copy link
Contributor Author

certik commented Nov 18, 2018

I've added tests on x86-64, the test uses lld to build an executable (without any dependencies, not even libc), then executes it and tests that it returns an exit code of 42. It works on all the Linux builds on Travis (in all Python versions). I think that is a very robust test that things actually work.

After lld is uploaded for a Mac and Windows, I can write similar tests for those two platforms (each platform requires a bit different LLVM IR to create an executable that only uses system calls, no libc). Also I think we need to extend our C++ LLD wrapper to include code for Mac and Windows, right now it only includes code for Linux.

@certik
Copy link
Contributor Author

certik commented Nov 27, 2018

@seibert, @stuartarchibald can you please help me get this merged? Let's make a plan what needs to be done and how.

This PR provides an extremely useful functionality, so that llvmlite can create executables without any external dependencies such as ld or gcc.

@seibert
Copy link
Contributor

seibert commented Nov 28, 2018

Sorry this has been delayed. You caught us during US Thanksgiving and preparations for the Numba release. Once that settles down in the next couple days, we can work on reviewing this. (We have a shorter dev cycle next, so this should be able to make it out in our mid-December release.)

@certik
Copy link
Contributor Author

certik commented Nov 28, 2018

Hi @seibert no problem. I just want to stress that it's not about sitting for 1h and merge. Likely you might want to do things a bit differently than I have done in this PR, and so it's about figuring a plan how to get this in, and then we have to execute the plan. In other words, it requires iterations between me and your team. So the sooner we begin these iterations the better.

@stuartarchibald
Copy link
Contributor

Thanks for the idea/patches. This is something that's been a struggle for e.g. the AMD GPU target compilation chain before, AFAIAA there is no programmatic API for lld and this causes much pain for in memory compilation. Before reviewing the specific details I think we need to discuss and make decisions about a few fundamental things:

  1. What does this gain?
    Assuming lld does not have an API to allow for invocation on in memory data in the way that most of the other LLVM tools do, does binding to the lld CLI gain anything more than e.g. simply shipping lld with llvmlite (or as a dependency) and having a shell wrapper?

  2. Should lld be built independently or as part of llvmdev?
    Whilst there may be some benefit in keeping it separate (potentially differing release cycles, llvm builds are CPU intensive etc) building it as part of llvmdev itself would mean that compilers, flags and other important internal build considerations are kept consistent between llvm and lld. Further, in terms of maintenance burden, whilst not hugely onerous, having a separate lld package would mean another package to ship, build and maintain across the Numba stack's 8 architecture/OS combinations. I also wonder about the impact on the consistency of llvm-config output.

  3. Is calling lld::elf::link sufficient to support all the potential linkable objects?
    I don't know the answer to this from memory but suspect not. If this is the case, we need to be very clear about what is supported. FWIW there's also the lld::coeff::link, lld::mach_o::link and lld::wasm::link entry points.

  4. Is lld sufficiently well supported across target platforms?
    To quote the docs https://releases.llvm.org/7.0.0/tools/lld/docs/index.html:

    It supports various CPUs/ABIs including x86-64, x86, x32, AArch64, ARM, MIPS 32/64 big/little-endian, PowerPC, PowerPC 64 and AMDGPU. Among these, x86-64 is the most well-supported target and have reached production quality. AArch64 and MIPS seem decent too. x86 should be OK but not well tested yet. ARM support is being developed actively.

    The platforms in the Numba stack are covered but evidently there are caveats about how well some of them will work. I think this risk is acceptable, putting the tool in the hands of more people will potentially help uncover bugs and the most prevalent architectures seem well-supported.

I think:

  • Resolving 1. will make it evident as to whether the design proposed in these patches is appropriate.
  • Resolving 2. will permit review of conda recipe changes.
  • Resolving 3. will permit review of the C++ and Python bindings.

Once 1. and 2. are resolved, with whatever conda recipe is decided upon, either a llvmdev rebuild based on this PR will need to be done, or a new job will need creating on the buildfarm for building and shipping lld, both just to get CI working. Assuming lld is accepted as part of the build in some manner it may be beneficial to split this PR into two, one that deals with building and shipping lld and then another that builds upon that so as to have working CI without having to loop back through the buildfarm.

@certik
Copy link
Contributor Author

certik commented Nov 29, 2018

Thanks @stuartarchibald for looking at this PR.

  1. It seems that indeed currently the lld::elf::link is the only supported API. However, as you mention later, putting the tool in the hands of more people can potentially help motivate a memory only API. Binding the LLD gains:
  • No runtime dependency on LLD (on my machine the LLD package is 16MB), but if it is binded with llvmlite, then the llvmlite package size only increased by 1MB on my computer (the size might further increase as we include coeff and other entry points, but likely it will still be much smaller than the LLD package itself)
  • No need to figure out where in the path the ld is, and ensure that it is there, and that it actually works with the LLVM version in llvmlite (for link time optimizations). By binding it, you know that it will just work by calling a simple Python function.
  • Makes llvmlite selfcontained, just a simple .so library that gets loaded into Python. No need to worry about a shell wrapper on all platforms and ensuring it works.
  • By shipping LLD separately, there is also a danger that it might not work with the LLVM version included in llvmlite. Consider this failure that I encountered: Add dependency on LLD, wrap it into Python #419 (comment), I was using the LLD from conda-forge, and that is incompatible with the LLVM in llvmlite. There might be more of such issues. By actually linking it with the rest of LLVM into the libllvmlite.so shared library, I think that ensures that most of these bugs are caught early.
  1. Yes, it is important to use compatible options for both llvmdev and LLD in order to avoid similar build failures as I was facing in Add dependency on LLD, wrap it into Python #419 (comment).
    I used a separate package because that's how conda-forge does it, and one has to download a separate tarball for the source of LLD anyway, but if you know how to do that as part of a single llvmdev package, that might be an option too. I am fine either way, as this is only a build time dependency anyway.

  2. What are some potential linkable objects that might not be supported? Let's document that.
    Yes, we need to wrap the other entry points, but I was going to do that once we settle on how to distribute LLD, and once we have LLD builds for Mac and Windows, so that we can actually test it on the CI.

  3. It seems it's sufficiently well supported for x86-64, and it seems the LLVM community is committed to the tool, and so this is a start, which will bring the tool to more people, and for my use case it seems to actually work great. And for other use cases when it does not work great, people can still use some other linker, as they have to now anyway. Since currently LLD requires to save the object files to disk, one can easily swap LLD for another linker if it turns out that LLD does not support something yet.

At the end of the day, llvmlite rises and falls with LLVM. Since LLD is part of LLVM, even if it's imperfect, it makes sense for llvmlite to wrap it. If it can't do everything that people want it to do, then LLVM/LLD itself has to be improved, not much we can do about it in llvmlite.

@stuartarchibald
Copy link
Contributor

@certik thanks for the responses.

  1. Replying to the points

    • No runtime dependency on LLD (on my machine the LLD package is 16MB), but if it is binded with llvmlite, then the llvmlite package size only increased by 1MB on my computer (the size might further increase as we include coeff and other entry points, but likely it will still be much smaller than the LLD package itself)

    Agreed, but a statically built lld binary is probably quite small, I imagine the whole package doesn't need to ship.

    • No need to figure out where in the path the ld is, and ensure that it is there, and that it actually works with the LLVM version in llvmlite (for link time optimizations). By binding it, you know that it will just work by calling a simple Python function.
    • Makes llvmlite selfcontained, just a simple .so library that gets loaded into Python. No need to worry about a shell wrapper on all platforms and ensuring it works.

    Indeed, most of this however is dealt with by conda packages. Paths are known, subprocess works fine etc.

    • By shipping LLD separately, there is also a danger that it might not work with the LLVM version included in llvmlite. Consider this failure that I encountered: Add dependency on LLD, wrap it into Python #419 (comment), I was using the LLD from conda-forge, and that is incompatible with the LLVM in llvmlite. There might be more of such issues. By actually linking it with the rest of LLVM into the libllvmlite.so shared library, I think that ensures that most of these bugs are caught early.

    I consider this area of most concern and therefore think exploring the option of compiling lld as part of llvm is worth while.

  2. Yes, conda supports multi-source builds.

  3. Anecdotally, from reading mailing lists, it seems like there's a few interesting things that can happen on windows with MinGW and possibly with COFF too. However, until they can be expressed concretely we shall not worry. As to how to proceed with lld distribution, see below.

  4. Agree.

I'm convinced of the merits of undertaking this, especially with view that at some point lld may get an improved API and in which case a load of the work to integrate and test it will already have been done. To proceed I propose the following:

  1. Try building lld as part of the llvmdev recipe that can be found here: https://github.com/numba/llvmlite/tree/master/conda-recipes/llvmdev. This will ensure issues like the noted Add dependency on LLD, wrap it into Python #419 (comment) are less likely to occur, it also provides consistency and hopefully will be picked up in llvm-config etc. which will make compilation of the llvmlite ffi interface easier. If this fails then split packages may have to be revisited.
  2. If 1. succeeds then that can be PR'd separately and a new build of llvmdev can be shipped as a basis for additional changes. The build out of llvmdev will be available for: [x86_64, x86] x [windows, linux], OSX, and linux with armv7l and AArch64. This should provide sufficient as a starting point for testing the lld::mach_o::link and lld::coff::linkbindings too.

Thoughts?

@certik
Copy link
Contributor Author

certik commented Nov 29, 2018

@stuartarchibald thanks. I think we agree on things and as long as you are convinced that this is worth doing, I actually don't really care one way or another, as long as this is done and part of llvmlite.

So I'll work on 1., I found documentation here: https://conda.io/docs/user-guide/tasks/build-packages/define-metadata.html#source-from-multiple-sources and send a separate PR.

@stuartarchibald
Copy link
Contributor

@certik no problem. I think that if you would find such a tool useful and would use it then it is worth doing. I would anticipate that other users would also find such a tool useful too. I can also see potential use for it in circumstances similar to those for the AMD GPU bindings.

Thanks for volunteering to try 1. if you get stuck then please shout. This may help: https://github.com/numba/roctools/blob/master/conda-recipes/llvmdev_amdgcn/meta.yaml

@certik
Copy link
Contributor Author

certik commented Nov 30, 2018

@stuartarchibald 1. is implemented in #428.

@certik
Copy link
Contributor Author

certik commented Jan 26, 2019

I rebased on top of the latest master. Indeed, things now work out of the box for Python 3.

The Python 2.7 tests are failing, due to the missing backports.tempfile package (https://travis-ci.org/numba/llvmlite/jobs/484868422#L1005). However, the package is correctly installed using pip here: https://travis-ci.org/numba/llvmlite/jobs/484868422#L674, so I don't understand what is going on. This used to work before I rebased the branch.

@stuartarchibald do you see anything wrong with this?

@certik
Copy link
Contributor Author

certik commented Jan 26, 2019

I figured it out --- I had to call pip after the line export PATH=/opt/python/$pyver/bin:$PATH. I tried to also install the backports.tempfile package using conda, but it's only available on conda-forge and then it fails later due to some incompatibilities (https://travis-ci.org/numba/llvmlite/jobs/484875871#L739). Now the Python 2.7 tests pass.

@certik
Copy link
Contributor Author

certik commented Jan 26, 2019

The linux tests now pass, the Windows test fails because it can't find the LLD libraries (https://ci.appveyor.com/project/seibert/llvmlite/builds/21913057#L1288). The Mac tests fail for the same reason. The PyPy test fails due to the missing backports module.

@certik
Copy link
Contributor Author

certik commented Jan 26, 2019

I created a TODO list in the PR description. @stuartarchibald let me know if you want to implement anything else, or if you don't want some of the items implemented before merging.

@stuartarchibald
Copy link
Contributor

Thanks for the fixups...

RE the TODO list, first, thanks for writing this:

  • Make all Travis tests pass, test LLD on 64bit linux
    • I think yes.
  • Write a test for 32 bits linux? Currently only 64 bits are tested.
    • I think not right now. Also these test assume x86* instruction set. llvmlite is built on and works with PPC64LE and ARMv7 (little endian) and AARCH64, but we can probably skip these for now so long as the unit tests guard against running on these architectures. When writing new features for the Numba stack it's necessary to consider appropriate combinations of [Linux, Windows, OSX] x [32 bit, 64 bit] x [x86, ARMv7, AARCH64, PPC64LE], and then either support them, or guard against their use if unsupported and document it as such.
  • Get it to compile on macOS
    • I think yes, or if it turns out to be too hard, skip it and raise NotImplementedError appropriately and document it well.
  • Get it to compile on Windows
    • As the previous.
  • Get the PyPy test working
    • Not for this PR, skip whatever it is that's breaking it.
  • Implement LLD for macOS and test it
    • Depending on how hard the compilation turns out, may be best to just raise NotImplementedError
  • Implement LLD for Windows and test it
    • As the previous.
  • Squash commits into a nice set of patches
    • Can just do this when pressing the merge button, so whatever is convenient.

We'll need to take a look at the backports.tempfile usage with view of whether llvmlite should carry another dependency, even in testing. Numba has similar functionality here https://github.com/numba/numba/blob/e475b97790a0dbdc5b255f332cdc7071b6327d62/numba/tests/support.py#L539 a less involved version of which could be replicated to provide the same?

@gmarkall gmarkall added this to the PR Backlog milestone Dec 20, 2021
@gmarkall
Copy link
Member

Many thanks for the PR and your efforts so far @certik!

I'm spending some time going through the llvmlite PR backlog - this PR seems to be one that's been stuck for a while. I see that in #311 (comment) @certik mentioned a lack of time to work on this PR.

I think for this PR to move forward, the following is required:

With the above said, would anyone with an interest in this functionality like to volunteer to take over this PR to bring it through to completion? Anyone who is interested, please:

  • Open a new PR based on the work of this one with a start on the necessary updates
  • Add a link to it from here and ping myself (@gmarkall).

@ArachnidAbby
Copy link

ArachnidAbby commented Jan 11, 2023

@gmarkall I decided to take a stab at it.

https://github.com/Hassium-Software/llvmlite-lld
(located in a random Organization since I couldn't have two forks of llvmlite)

I have the commits from the PR working in modern llvmlite. I also fixed ffi/lld.cpp which was complaining about too few arguments for lld::elf::link(...).

I will continue to work on this and see what I can do. I was just hoping for feedback on the changes I made to that cpp file. I have very little knowledge of cpp or the internal workings of llvm.

edit:

  • New llvmlite.binding.lld package exists
  • lld_main() now returns the string output of the command
  • lld_<platform>() functions now exist. They take an output file name a list of input object file names, and an optional list of arguments. ex: lld_linux("output", ["main.o"])
  • lld_auto takes the same arguments as the other lld functions but has an additional add_extensions boolean that toggles automatically adding the file extension for the binary on the platform detected. For example: if the platform is windows when running the function, it will automatically add .exe to the end of the output file name.

@gmarkall
Copy link
Member

@spidertyler2005 Many thanks for taking a look at this!

I have the commits from the PR working in modern llvmlite. I also fixed ffi/lld.cpp which was complaining about too few arguments for lld::elf::link(...).

I will continue to work on this and see what I can do. I was just hoping for feedback on the changes I made to that cpp file. I have very little knowledge of cpp or the internal workings of llvm.

This sounds great!

Could you please open a new PR from your fork / branch so we can discuss your work there and reference it more directly?

(located in a random Organization since I couldn't have two forks of llvmlite)

You could have multiple branches in your fork though - for example, I have several current branches in my llvmlite fork (orcjit, orcjit-llvm15, etc.): https://github.com/gmarkall/llvmlite/branches

@ArachnidAbby ArachnidAbby mentioned this pull request Jan 11, 2023
12 tasks
@gmarkall
Copy link
Member

Closing this as #898 carries on this work and is now ready for review.

Thanks @certik with your efforts so far on this and getting the ball rolling!

Thanks @spidertyler2005 for continuing it!

@gmarkall gmarkall closed this Jan 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow llvmlite to also link object code
7 participants