forked from conan-io/conan-center-index
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(conan-io#3375) Add recipe for the LLVM core libraries
* Added recipe for the LLVM core libraries * Reuse cmake configuration * Fix shared builds for 10x and 11x * Parse dependencies from graphviz output * Beware of dummy targets * Keep only latest version for the moment * Beware of Windows line endings * Relax cmake version requirement * Add list of unsupported compiler configurations * Commit suggestion Co-authored-by: Yoann Potinet <intelligide@hotmail.fr> * Cannot discriminate Visual Studio by its minor version Visual Studio version 16.4, which is known by miscompiling LLVM, is currently being used by conan-center-index's CCI. Let's use LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN to make that compilation pass until Visual Studio is upgraded. * Disable object targets properly * Use external dependencies properly * Enable building with libffi in Windows * Do not force libc++ in clang builds * Wrong value for a cmake flag * Building native tools were making some configurations fail * Allow Visual Studio generators now that native tools are disabled * Disable relative paths for the sources in the debug info The latest versions of clang were not able to find the standard library headers if compiling with `-stdlib=libc++` and `-no-canonical-prefixes`. * Update supported compilers * String comparisons are dangerous * Remove iconv patch comment Turns out that the hack was justified. Both, iconv and charset libraries, own a localcharset symbol. In normal circumstances this is not an issue but libLLVM gets linked with `--whole-archive` or `-all_load` and the linker complains about duplicated symbols. It is safer to remove charset from the linking step, as its symbols are not needed, than to remove the linker option. * Commit suggestion Co-authored-by: Yoann Potinet <intelligide@hotmail.fr> * More meaningful exception messages * Remove unnecessary readme * Support older Python versions It is such a pity; pathlib is way elegant than os.path. * Empty commit to trigger the CI * Remove unnecessary status message Co-authored-by: Michael Keck <git@cr0ydon.com> * Less strict cmake minimum required version Co-authored-by: Michael Keck <git@cr0ydon.com> * LLVM version bumped to 11.0.1 * LLVM version bumped to 11.1.0 * Deactivate fPIC if shared * Fix fPIC flag for shared builds * Install LLVMTableGenGlobalISel manually As it is not part of the install target. This is a kind of problematic library, see: https://reviews.llvm.org/D74588 * Add option use_sanitizer * Disable all shared builds * Dedent conandata.yml Co-authored-by: Yoann Potinet <intelligide@hotmail.fr> Co-authored-by: Yoann Potinet <intelligide@hotmail.fr> Co-authored-by: Michael Keck <git@cr0ydon.com>
- Loading branch information
Showing
11 changed files
with
594 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
cmake_minimum_required(VERSION 3.13.4) | ||
project(conanllvm) | ||
|
||
include(${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo.cmake) | ||
conan_basic_setup() | ||
|
||
add_subdirectory("source") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
sources: | ||
"11.1.0": | ||
url: https://github.com/llvm/llvm-project/releases/download/llvmorg-11.1.0/llvm-11.1.0.src.tar.xz | ||
sha256: ce8508e318a01a63d4e8b3090ab2ded3c598a50258cc49e2625b9120d4c03ea5 | ||
|
||
patches: | ||
"11.1.0": | ||
- base_path: "source" | ||
patch_file: "patches/11.1.0-vs2019.patch" | ||
- base_path: "source" | ||
patch_file: "patches/11.1.0-cmake.patch" | ||
- base_path: "source" | ||
patch_file: "patches/11.1.0-native.patch" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,319 @@ | ||
from conans.errors import ConanInvalidConfiguration | ||
from conans import ConanFile, CMake, tools | ||
|
||
from collections import defaultdict | ||
import json | ||
import re | ||
import os.path | ||
import os | ||
|
||
|
||
class LLVMCoreConan(ConanFile): | ||
name = 'llvm-core' | ||
description = ( | ||
'A toolkit for the construction of highly optimized compilers,' | ||
'optimizers, and runtime environments.' | ||
) | ||
license = 'Apache-2.0 WITH LLVM-exception' | ||
topics = ('conan', 'llvm') | ||
homepage = 'https://github.com/llvm/llvm-project/tree/master/llvm' | ||
url = 'https://github.com/conan-io/conan-center-index' | ||
|
||
settings = ('os', 'arch', 'compiler', 'build_type') | ||
options = { | ||
'shared': [True, False], | ||
'fPIC': [True, False], | ||
'components': 'ANY', | ||
'targets': 'ANY', | ||
'exceptions': [True, False], | ||
'rtti': [True, False], | ||
'threads': [True, False], | ||
'lto': ['On', 'Off', 'Full', 'Thin'], | ||
'static_stdlib': [True, False], | ||
'unwind_tables': [True, False], | ||
'expensive_checks': [True, False], | ||
'use_perf': [True, False], | ||
'use_sanitizer': [ | ||
'Address', | ||
'Memory', | ||
'MemoryWithOrigins', | ||
'Undefined', | ||
'Thread', | ||
'DataFlow', | ||
'Address;Undefined', | ||
'None' | ||
], | ||
'with_ffi': [True, False], | ||
'with_zlib': [True, False], | ||
'with_xml2': [True, False] | ||
} | ||
default_options = { | ||
'shared': False, | ||
'fPIC': True, | ||
'components': 'all', | ||
'targets': 'all', | ||
'exceptions': True, | ||
'rtti': True, | ||
'threads': True, | ||
'lto': 'Off', | ||
'static_stdlib': False, | ||
'unwind_tables': True, | ||
'expensive_checks': False, | ||
'use_perf': False, | ||
'use_sanitizer': 'None', | ||
'with_ffi': False, | ||
'with_zlib': True, | ||
'with_xml2': True | ||
} | ||
|
||
exports_sources = ['CMakeLists.txt', 'patches/*'] | ||
generators = ['cmake', 'cmake_find_package'] | ||
no_copy_source = True | ||
|
||
@property | ||
def _source_subfolder(self): | ||
return 'source' | ||
|
||
def _supports_compiler(self): | ||
compiler = self.settings.compiler.value | ||
version = tools.Version(self.settings.compiler.version) | ||
major_rev, minor_rev = int(version.major), int(version.minor) | ||
|
||
unsupported_combinations = [ | ||
[compiler == 'gcc', major_rev == 5, minor_rev < 1], | ||
[compiler == 'gcc', major_rev < 5], | ||
[compiler == 'clang', major_rev < 4], | ||
[compiler == 'apple-clang', major_rev < 9], | ||
[compiler == 'Visual Studio', major_rev < 15] | ||
] | ||
if any(all(combination) for combination in unsupported_combinations): | ||
message = 'unsupported compiler: "{}", version "{}"' | ||
raise ConanInvalidConfiguration(message.format(compiler, version)) | ||
|
||
def _patch_sources(self): | ||
for patch in self.conan_data.get('patches', {}).get(self.version, []): | ||
tools.patch(**patch) | ||
|
||
def _patch_build(self): | ||
if os.path.exists('FindIconv.cmake'): | ||
tools.replace_in_file('FindIconv.cmake', 'iconv charset', 'iconv') | ||
|
||
def _configure_cmake(self): | ||
cmake = CMake(self) | ||
cmake.definitions['BUILD_SHARED_LIBS'] = False | ||
cmake.definitions['CMAKE_SKIP_RPATH'] = True | ||
cmake.definitions['CMAKE_POSITION_INDEPENDENT_CODE'] = \ | ||
self.options.get_safe('fPIC', default=False) or self.options.shared | ||
|
||
if not self.options.shared: | ||
cmake.definitions['DISABLE_LLVM_LINK_LLVM_DYLIB'] = True | ||
# cmake.definitions['LLVM_LINK_DYLIB'] = self.options.shared | ||
|
||
cmake.definitions['LLVM_TARGET_ARCH'] = 'host' | ||
cmake.definitions['LLVM_TARGETS_TO_BUILD'] = self.options.targets | ||
cmake.definitions['LLVM_BUILD_LLVM_DYLIB'] = self.options.shared | ||
cmake.definitions['LLVM_DYLIB_COMPONENTS'] = self.options.components | ||
cmake.definitions['LLVM_ENABLE_PIC'] = \ | ||
self.options.get_safe('fPIC', default=False) | ||
|
||
cmake.definitions['LLVM_ABI_BREAKING_CHECKS'] = 'WITH_ASSERTS' | ||
cmake.definitions['LLVM_ENABLE_WARNINGS'] = True | ||
cmake.definitions['LLVM_ENABLE_PEDANTIC'] = True | ||
cmake.definitions['LLVM_ENABLE_WERROR'] = False | ||
|
||
cmake.definitions['LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN'] = True | ||
cmake.definitions['LLVM_USE_RELATIVE_PATHS_IN_DEBUG_INFO'] = False | ||
cmake.definitions['LLVM_BUILD_INSTRUMENTED_COVERAGE'] = False | ||
cmake.definitions['LLVM_OPTIMIZED_TABLEGEN'] = True | ||
cmake.definitions['LLVM_REVERSE_ITERATION'] = False | ||
cmake.definitions['LLVM_ENABLE_BINDINGS'] = False | ||
cmake.definitions['LLVM_CCACHE_BUILD'] = False | ||
|
||
cmake.definitions['LLVM_INCLUDE_TOOLS'] = self.options.shared | ||
cmake.definitions['LLVM_INCLUDE_EXAMPLES'] = False | ||
cmake.definitions['LLVM_INCLUDE_TESTS'] = False | ||
cmake.definitions['LLVM_INCLUDE_BENCHMARKS'] = False | ||
cmake.definitions['LLVM_APPEND_VC_REV'] = False | ||
cmake.definitions['LLVM_BUILD_DOCS'] = False | ||
cmake.definitions['LLVM_ENABLE_IDE'] = False | ||
|
||
cmake.definitions['LLVM_ENABLE_EH'] = self.options.exceptions | ||
cmake.definitions['LLVM_ENABLE_RTTI'] = self.options.rtti | ||
cmake.definitions['LLVM_ENABLE_THREADS'] = self.options.threads | ||
cmake.definitions['LLVM_ENABLE_LTO'] = self.options.lto | ||
cmake.definitions['LLVM_STATIC_LINK_CXX_STDLIB'] = \ | ||
self.options.static_stdlib | ||
cmake.definitions['LLVM_ENABLE_UNWIND_TABLES'] = \ | ||
self.options.unwind_tables | ||
cmake.definitions['LLVM_ENABLE_EXPENSIVE_CHECKS'] = \ | ||
self.options.expensive_checks | ||
cmake.definitions['LLVM_ENABLE_ASSERTIONS'] = \ | ||
self.settings.build_type == 'Debug' | ||
|
||
cmake.definitions['LLVM_USE_NEWPM'] = False | ||
cmake.definitions['LLVM_USE_OPROFILE'] = False | ||
cmake.definitions['LLVM_USE_PERF'] = self.options.use_perf | ||
if self.options.use_sanitizer == 'None': | ||
cmake.definitions['LLVM_USE_SANITIZER'] = '' | ||
else: | ||
cmake.definitions['LLVM_USE_SANITIZER'] = \ | ||
self.options.use_sanitizer | ||
|
||
cmake.definitions['LLVM_ENABLE_Z3_SOLVER'] = False | ||
cmake.definitions['LLVM_ENABLE_LIBPFM'] = False | ||
cmake.definitions['LLVM_ENABLE_LIBEDIT'] = False | ||
cmake.definitions['LLVM_ENABLE_FFI'] = self.options.with_ffi | ||
cmake.definitions['LLVM_ENABLE_ZLIB'] = \ | ||
self.options.get_safe('with_zlib', False) | ||
cmake.definitions['LLVM_ENABLE_LIBXML2'] = \ | ||
self.options.get_safe('with_xml2', False) | ||
return cmake | ||
|
||
def config_options(self): | ||
if self.settings.os == 'Windows': | ||
del self.options.fPIC | ||
del self.options.with_zlib | ||
del self.options.with_xml2 | ||
|
||
def requirements(self): | ||
if self.options.with_ffi: | ||
self.requires('libffi/3.3') | ||
if self.options.get_safe('with_zlib', False): | ||
self.requires('zlib/1.2.11') | ||
if self.options.get_safe('with_xml2', False): | ||
self.requires('libxml2/2.9.10') | ||
|
||
def configure(self): | ||
if self.options.shared: # Shared builds disabled just due to the CI | ||
message = 'Shared builds not currently supported' | ||
raise ConanInvalidConfiguration(message) | ||
# del self.options.fPIC | ||
# if self.settings.os == 'Windows' and self.options.shared: | ||
# message = 'Shared builds not supported on Windows' | ||
# raise ConanInvalidConfiguration(message) | ||
if self.options.exceptions and not self.options.rtti: | ||
message = 'Cannot enable exceptions without rtti support' | ||
raise ConanInvalidConfiguration(message) | ||
self._supports_compiler() | ||
|
||
def source(self): | ||
tools.get(**self.conan_data['sources'][self.version]) | ||
os.rename('llvm-{}.src'.format(self.version), self._source_subfolder) | ||
self._patch_sources() | ||
|
||
def build(self): | ||
self._patch_build() | ||
cmake = self._configure_cmake() | ||
cmake.configure() | ||
cmake.build() | ||
|
||
def package(self): | ||
self.copy('LICENSE.TXT', dst='licenses', src=self._source_subfolder) | ||
lib_path = os.path.join(self.package_folder, 'lib') | ||
|
||
cmake = self._configure_cmake() | ||
cmake.install() | ||
|
||
if not self.options.shared: | ||
for ext in ['.a', '.lib']: | ||
lib = '*LLVMTableGenGlobalISel{}'.format(ext) | ||
self.copy(lib, dst='lib', src='lib') | ||
|
||
self.run('cmake --graphviz=graph/llvm.dot .') | ||
with tools.chdir('graph'): | ||
dot_text = tools.load('llvm.dot').replace('\r\n', '\n') | ||
|
||
dep_regex = re.compile(r'//\s(.+)\s->\s(.+)$', re.MULTILINE) | ||
deps = re.findall(dep_regex, dot_text) | ||
|
||
dummy_targets = defaultdict(list) | ||
for target, dep in deps: | ||
if not target.startswith('LLVM'): | ||
dummy_targets[target].append(dep) | ||
|
||
cmake_targets = { | ||
'libffi::libffi': 'ffi', | ||
'ZLIB::ZLIB': 'z', | ||
'Iconv::Iconv': 'iconv', | ||
'LibXml2::LibXml2': 'xml2' | ||
} | ||
|
||
components = defaultdict(list) | ||
for lib, dep in deps: | ||
if not lib.startswith('LLVM'): | ||
continue | ||
elif dep.startswith('-delayload:'): | ||
continue | ||
elif dep.startswith('LLVM'): | ||
components[dep] | ||
elif dep in cmake_targets: | ||
dep = cmake_targets[dep] | ||
elif os.path.exists(dep): | ||
dep = os.path.splitext(os.path.basename(dep))[0] | ||
dep = dep.replace('lib', '') | ||
dep = dep.replace('-l', '') | ||
|
||
if dep in dummy_targets.keys(): | ||
components[lib].extend(dummy_targets[dep]) | ||
components[lib] = list(set(components[lib])) | ||
else: | ||
components[lib].append(dep) | ||
|
||
tools.rmdir(os.path.join(self.package_folder, 'bin')) | ||
tools.rmdir(os.path.join(self.package_folder, 'lib', 'cmake')) | ||
tools.rmdir(os.path.join(self.package_folder, 'share')) | ||
|
||
for name in os.listdir(lib_path): | ||
if 'LLVM' not in name: | ||
os.remove(os.path.join(lib_path, name)) | ||
|
||
if not self.options.shared: | ||
components_path = \ | ||
os.path.join(self.package_folder, 'lib', 'components.json') | ||
with open(components_path, 'w') as components_file: | ||
json.dump(components, components_file, indent=4) | ||
else: | ||
suffixes = ['.dylib', '.so'] | ||
for name in os.listdir(lib_path): | ||
if not any(suffix in name for suffix in suffixes): | ||
os.remove(os.path.join(lib_path, name)) | ||
|
||
def package_info(self): | ||
if self.options.shared: | ||
self.cpp_info.libs = tools.collect_libs(self) | ||
if self.settings.os == 'Linux': | ||
self.cpp_info.system_libs = ['tinfo', 'pthread'] | ||
self.cpp_info.system_libs.extend(['rt', 'dl', 'm']) | ||
elif self.settings.os == 'Macos': | ||
self.cpp_info.system_libs = ['curses', 'm'] | ||
return | ||
|
||
components_path = \ | ||
os.path.join(self.package_folder, 'lib', 'components.json') | ||
with open(components_path, 'r') as components_file: | ||
components = json.load(components_file) | ||
|
||
dependencies = ['ffi', 'z', 'iconv', 'xml2'] | ||
targets = { | ||
'ffi': 'libffi::libffi', | ||
'z': 'zlib::zlib', | ||
'xml2': 'libxml2::libxml2' | ||
} | ||
|
||
for lib, deps in components.items(): | ||
component = lib[4:].replace('LLVM', '').lower() | ||
|
||
self.cpp_info.components[component].libs = [lib] | ||
|
||
self.cpp_info.components[component].requires = [ | ||
dep[4:].replace('LLVM', '').lower() | ||
for dep in deps if dep.startswith('LLVM') | ||
] | ||
for lib, target in targets.items(): | ||
if lib in deps: | ||
self.cpp_info.components[component].requires.append(target) | ||
|
||
self.cpp_info.components[component].system_libs = [ | ||
dep for dep in deps | ||
if not dep.startswith('LLVM') and dep not in dependencies | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
--- cmake/config-ix.cmake | ||
+++ cmake/config-ix.cmake | ||
@@ -159,6 +159,9 @@ | ||
set(LIBXML2_FOUND 0) | ||
if((LLVM_ENABLE_LIBXML2) AND ((CMAKE_SYSTEM_NAME MATCHES "Linux") AND (ICONV_LIBRARY_PATH) OR APPLE)) | ||
find_package(LibXml2) | ||
+ set(LIBXML2_FOUND 1) | ||
+ list(GET LibXml2_INCLUDE_DIRS -1 LIBXML2_INCLUDE_DIR) | ||
+ set(LIBXML2_LIBRARIES ${LibXml2_LIBRARIES}) | ||
if (LIBXML2_FOUND) | ||
set(LLVM_LIBXML2_ENABLED 1) | ||
if ((CMAKE_OSX_SYSROOT) AND (EXISTS ${CMAKE_OSX_SYSROOT}/${LIBXML2_INCLUDE_DIR})) | ||
@@ -321,7 +321,7 @@ | ||
message(FATAL_ERROR "libffi includes are not found.") | ||
endif() | ||
|
||
- find_library(FFI_LIBRARY_PATH ffi PATHS ${FFI_LIBRARY_DIR}) | ||
+ find_library(FFI_LIBRARY_PATH NAMES ffi libffi PATHS ${FFI_LIBRARY_DIR}) | ||
if( NOT FFI_LIBRARY_PATH ) | ||
message(FATAL_ERROR "libffi is not found.") | ||
endif() | ||
--- cmake/modules/TableGen.cmake | ||
+++ cmake/modules/TableGen.cmake | ||
@@ -138,12 +138,7 @@ | ||
macro(add_tablegen target project) | ||
set(${target}_OLD_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS}) | ||
set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} TableGen) | ||
- | ||
- # CMake-3.9 doesn't let compilation units depend on their dependent libraries. | ||
- if(NOT (CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_VERSION VERSION_LESS 3.9) AND NOT XCODE) | ||
- # FIXME: It leaks to user, callee of add_tablegen. | ||
- set(LLVM_ENABLE_OBJLIB ON) | ||
- endif() | ||
+ set(LLVM_ENABLE_OBJLIB OFF) | ||
|
||
add_llvm_executable(${target} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN}) | ||
set(LLVM_LINK_COMPONENTS ${${target}_OLD_LLVM_LINK_COMPONENTS}) | ||
--- lib/WindowsManifest/CMakeLists.txt | ||
+++ lib/WindowsManifest/CMakeLists.txt | ||
@@ -8,16 +8,6 @@ | ||
if(LIBXML2_LIBRARIES) | ||
target_link_libraries(LLVMWindowsManifest PUBLIC ${LIBXML2_LIBRARIES}) | ||
|
||
- get_filename_component(xml2_library ${LIBXML2_LIBRARIES} NAME) | ||
- if (CMAKE_STATIC_LIBRARY_PREFIX AND | ||
- xml2_library MATCHES "^${CMAKE_STATIC_LIBRARY_PREFIX}.*${CMAKE_STATIC_LIBRARY_SUFFIX}$") | ||
- string(REGEX REPLACE "^${CMAKE_STATIC_LIBRARY_PREFIX}" "" xml2_library ${xml2_library}) | ||
- string(REGEX REPLACE "${CMAKE_STATIC_LIBRARY_SUFFIX}$" "" xml2_library ${xml2_library}) | ||
- elseif (CMAKE_SHARED_LIBRARY_PREFIX AND | ||
- xml2_library MATCHES "^${CMAKE_SHARED_LIBRARY_PREFIX}.*${CMAKE_SHARED_LIBRARY_SUFFIX}$") | ||
- string(REGEX REPLACE "^${CMAKE_SHARED_LIBRARY_PREFIX}" "" xml2_library ${xml2_library}) | ||
- string(REGEX REPLACE "${CMAKE_SHARED_LIBRARY_SUFFIX}$" "" xml2_library ${xml2_library}) | ||
- endif() | ||
set_property(TARGET LLVMWindowsManifest PROPERTY | ||
- LLVM_SYSTEM_LIBS ${xml2_library}) | ||
+ LLVM_SYSTEM_LIBS ${LIBXML2_LIBRARIES}) | ||
endif() |
Oops, something went wrong.