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

Introduce libc subsystem to find crti.o on linux hosts and unskip the native backend subsystem tests #5943

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
1de3dcb
depend on glibc on linux to compile python_dist()s
cosmicexplorer Jun 8, 2018
7e4eb1f
fix llvm select() and unskip the native toolchain subsystem tests
cosmicexplorer Jun 8, 2018
673455c
update default version of glibc as per pantsbuild/binaries#70
cosmicexplorer Jun 11, 2018
88e6050
remove glibc, and remove executable step from native subsystem tests
cosmicexplorer Jun 14, 2018
d0b9a41
set LDSHARED when invoking a setup.py and test making an exe with gcc
cosmicexplorer Jun 14, 2018
56b5664
Revert "remove glibc, and remove executable step from native subsyste…
cosmicexplorer Jun 14, 2018
26cc81d
remove glibc again
cosmicexplorer Jun 14, 2018
536ec1e
add the libc subsystem to find the host libc
cosmicexplorer Jun 14, 2018
5e1815f
fix ldd output parsing
cosmicexplorer Jun 14, 2018
9a2d04a
fill out one of the exception messages for libc resolution
cosmicexplorer Jun 14, 2018
660ad3e
change get_joined_path -> create_path_env_var and add safe_shlex_join
cosmicexplorer Jun 14, 2018
0b3ec6b
add libc resolution for crti.o through gcc -print-search-dirs
cosmicexplorer Jun 14, 2018
32ba98c
upgrade xcode cli tools and flesh out all coments/docstrings
cosmicexplorer Jun 14, 2018
712a481
expand fixmes
cosmicexplorer Jun 14, 2018
9cda245
remove outstanding FIXMEs by adding glibc crti dir to compiler tests
cosmicexplorer Jun 14, 2018
3cea0c8
improve error messages for libc resolution
cosmicexplorer Jun 14, 2018
23d1c5a
add the --libc-dir option, if you don't have a compiler installed
cosmicexplorer Jun 15, 2018
41d1ff0
remove absurd typo
cosmicexplorer Jun 15, 2018
6bd2741
fix incorrect import file
cosmicexplorer Jun 15, 2018
51481f6
introduce ParseSearchDirs to abstract getting library dirs from a com…
cosmicexplorer Jun 21, 2018
9456e54
use ParseSearchDirs in native toolchain subsystem testing
cosmicexplorer Jun 21, 2018
ce66e17
add path_entries to ParseSearchDirs
cosmicexplorer Jun 21, 2018
154e8bc
be a little better about using path entries if provided and not if not
cosmicexplorer Jun 21, 2018
baede6b
add another required exception wrapper
cosmicexplorer Jun 22, 2018
30abf7e
try to fix everything after rebasing
cosmicexplorer Jun 22, 2018
81bfd22
make ctypes testing pass again
cosmicexplorer Jun 22, 2018
511a8a6
native toolchain subsystem tests can create executables!!
cosmicexplorer Jun 22, 2018
916d206
make another test pass
cosmicexplorer Jun 22, 2018
518ab98
make all the other tests work too
cosmicexplorer Jun 23, 2018
55c815b
make python_dist() integration tests pass
cosmicexplorer Jun 23, 2018
f1065ba
test that we can use either compiler to produce executables!!!
cosmicexplorer Jun 23, 2018
2dfc9ab
fix a few mistakes
cosmicexplorer Jun 23, 2018
4d5fd49
remove duplicate llvm.py
cosmicexplorer Jun 23, 2018
529b03d
actually use our painstakingly constructed environments
cosmicexplorer Jun 23, 2018
4b28f23
add a subsystem dep on gcc for bootstrapping llvm
cosmicexplorer Jun 23, 2018
5a4082d
improve the docstring for ParseSearchDirs
cosmicexplorer Jun 23, 2018
b228290
add gcc resources to clang
cosmicexplorer Jun 23, 2018
82b7397
switch the clang compiler source to xcode on osx
cosmicexplorer Jun 23, 2018
4470d53
use the right flag joining method, not path joining
cosmicexplorer Jun 23, 2018
0c79d2a
add the appropriate args to compile and link on osx, hopefully
cosmicexplorer Jun 23, 2018
916d711
fix lint
cosmicexplorer Jun 23, 2018
feab754
document the environment we bring to the linker
cosmicexplorer Jun 23, 2018
45a2f88
add clang libs to gcc invocation in native toolchain testing
cosmicexplorer Jun 24, 2018
a33e258
add clang libs to g++
cosmicexplorer Jun 24, 2018
2db196a
hardcoding in some default search dirs to own the libs
cosmicexplorer Jun 25, 2018
10547c7
fix typo
cosmicexplorer Jun 25, 2018
24dcd7b
move LIBRARY_PATH back to the linker where it belongs
cosmicexplorer Jun 25, 2018
cb5c63a
refactor XCodeCLITools's method of finding files
cosmicexplorer Jun 27, 2018
08a22a8
remove unnecessary linker args
cosmicexplorer Jun 27, 2018
58fa60c
use our own clang to compile in the native toolchain testing on osx
cosmicexplorer Jun 27, 2018
635d3a3
remove extra compile link args and manually add some extra include paths
cosmicexplorer Jun 27, 2018
2510af8
move all the platform-specific logic into native_toolchain.py
cosmicexplorer Jun 27, 2018
318f5d5
fix the broken stuff left over from the previous commit
cosmicexplorer Jun 27, 2018
548b541
actually add the include dirs to gcc, which was the whole point of th…
cosmicexplorer Jun 27, 2018
cf0347c
remove unused products dir
cosmicexplorer Jun 27, 2018
071ea81
move almost all of the platform-specific nonsense into native_toolcha…
cosmicexplorer Jun 27, 2018
731eab8
add version testing and fix tuple index
cosmicexplorer Jun 27, 2018
045395d
use the LLVMCCompiler and LLVMCppCompiler from the NativeToolchain on…
cosmicexplorer Jun 27, 2018
fcb52df
refactor setup_py.py to add env vars manually because they don't comp…
cosmicexplorer Jun 27, 2018
4791dad
add some search dirs back to gcc
cosmicexplorer Jun 27, 2018
b041a7d
start some cleanup
cosmicexplorer Jun 27, 2018
42e0c60
remove HostLibcDevInstallation
cosmicexplorer Jun 27, 2018
1449300
refactor setup py native environment creation again
cosmicexplorer Jun 27, 2018
8db17b4
some more mild cleanup
cosmicexplorer Jun 27, 2018
54956c5
flesh out the last few fixmes
cosmicexplorer Jun 27, 2018
315b17b
fix some mistakes -- hopefully travis agrees
cosmicexplorer Jun 27, 2018
12987d8
don't assign a list to the environment
cosmicexplorer Jun 28, 2018
9dd3b28
use gcc specifically to link
cosmicexplorer Jun 28, 2018
ed14aef
rebasing is hard
cosmicexplorer Jun 28, 2018
691db6f
use clang++ to link c++ and clear up a fixme
cosmicexplorer Jun 28, 2018
330eb2a
add hopefully the final workaround
cosmicexplorer Jun 28, 2018
a4fc486
respond to review comments
cosmicexplorer Jun 28, 2018
a4c9b3e
remove fake news
cosmicexplorer Jun 28, 2018
08ba46d
use is_readable_dir wherever possible
cosmicexplorer Jun 29, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-support/bin/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Usage: $0 (-h|-fxbkmsrjlpuyncia)
-f skip python code formatting checks
-x skip bootstrap clean-all (assume bootstrapping from a
fresh clone)
-b skip bootstraping pants from local sources
-b skip bootstrapping pants from local sources
-k skip bootstrapped pants self compile check
-m skip sanity checks of bootstrapped pants and repo BUILD
files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import os
from collections import namedtuple

from pants.util.contextutil import get_joined_path
from pants.util.process_handler import subprocess
from pants.util.strutil import create_path_env_var


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -41,7 +41,7 @@ def _prepare_env(self, kwargs):
"""
kwargs = kwargs.copy()
env = kwargs.pop('env', os.environ).copy()
env['PATH'] = get_joined_path(self.extra_paths, env=env, prepend=True)
env['PATH'] = create_path_env_var(self.extra_paths, env=env, prepend=True)
return env, kwargs

def run(self, **kwargs):
Expand Down
121 changes: 113 additions & 8 deletions src/python/pants/backend/native/config/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)

import os
from abc import abstractproperty

from pants.engine.rules import SingletonRule
from pants.util.objects import datatype
from pants.util.osutil import all_normalized_os_names, get_normalized_os_name
from pants.util.strutil import create_path_env_var, safe_shlex_join


class Platform(datatype(['normalized_os_name'])):
Expand Down Expand Up @@ -49,33 +51,136 @@ def path_entries(self):
This may be multiple directories, e.g. if the main executable program invokes any subprocesses.
"""

@abstractproperty
def library_dirs(self):
"""Directories containing shared libraries required for a subprocess to run."""

@abstractproperty
def exe_filename(self):
"""The "entry point" -- which file to invoke when PATH is set to `path_entries()`."""

def get_invocation_environment_dict(self, platform):
lib_env_var = platform.resolve_platform_specific({
'darwin': lambda: 'DYLD_LIBRARY_PATH',
'linux': lambda: 'LD_LIBRARY_PATH',
})
return {
'PATH': create_path_env_var(self.path_entries),
lib_env_var: create_path_env_var(self.library_dirs),
}

class Linker(datatype([

class Assembler(datatype([
'path_entries',
'exe_filename',
('platform', Platform),
'library_dirs',
]), Executable):
pass


class CCompiler(datatype([
class Linker(datatype([
'path_entries',
'exe_filename',
('platform', Platform),
'library_dirs',
]), Executable):
pass

# FIXME(#5951): We need a way to compose executables more hygienically. This could be done
# declaratively -- something like: { 'LIBRARY_PATH': DelimitedPathDirectoryEnvVar(...) }. We
# could also just use safe_shlex_join() and create_path_env_var() and keep all the state in the
# environment -- but then we have to remember to use those each time we specialize.
def get_invocation_environment_dict(self, platform):
ret = super(Linker, self).get_invocation_environment_dict(platform).copy()

# TODO: set all LDFLAGS in here or in further specializations of Linker instead of in individual
# tasks.
all_ldflags_for_platform = platform.resolve_platform_specific({
'darwin': lambda: ['-mmacosx-version-min=10.11'],
'linux': lambda: [],
})
ret.update({
'LDSHARED': self.exe_filename,
# FIXME: this overloads the meaning of 'library_dirs' to also mean "directories containing
# static libraries required for creating an executable" (currently, libc). These concepts
# should be distinct.
'LIBRARY_PATH': create_path_env_var(self.library_dirs),
'LDFLAGS': safe_shlex_join(all_ldflags_for_platform),
})

return ret


class CompilerMixin(Executable):

@abstractproperty
def include_dirs(self):
"""Directories to search for header files to #include during compilation."""

# FIXME: LIBRARY_PATH and (DY)?LD_LIBRARY_PATH are used for entirely different purposes, but are
# both sourced from the same `self.library_dirs`!
def get_invocation_environment_dict(self, platform):
ret = super(CompilerMixin, self).get_invocation_environment_dict(platform).copy()

if self.include_dirs:
ret['CPATH'] = create_path_env_var(self.include_dirs)

all_cflags_for_platform = platform.resolve_platform_specific({
'darwin': lambda: ['-mmacosx-version-min=10.11'],
'linux': lambda: [],
})
ret['CFLAGS'] = safe_shlex_join(all_cflags_for_platform)

return ret


class CCompiler(datatype([
'path_entries',
'exe_filename',
'library_dirs',
'include_dirs',
]), CompilerMixin):

def get_invocation_environment_dict(self, platform):
ret = super(CCompiler, self).get_invocation_environment_dict(platform).copy()

ret['CC'] = self.exe_filename

return ret


class CppCompiler(datatype([
'path_entries',
'exe_filename',
('platform', Platform),
]), Executable):
pass
'library_dirs',
'include_dirs',
]), CompilerMixin):

def get_invocation_environment_dict(self, platform):
ret = super(CppCompiler, self).get_invocation_environment_dict(platform).copy()

ret['CXX'] = self.exe_filename

return ret


# TODO(#4020): These classes are performing the work of variants.
class GCCCCompiler(datatype([('c_compiler', CCompiler)])): pass


class LLVMCCompiler(datatype([('c_compiler', CCompiler)])): pass


class GCCCppCompiler(datatype([('cpp_compiler', CppCompiler)])): pass


class LLVMCppCompiler(datatype([('cpp_compiler', CppCompiler)])): pass


# FIXME: make this an @rule, after we can automatically produce LibcDev and other subsystems in the
# v2 engine (see #5788).
class HostLibcDev(datatype(['crti_object', 'fingerprint'])):

def get_lib_dir(self):
return os.path.dirname(self.crti_object)


def create_native_environment_rules():
Expand Down
1 change: 1 addition & 0 deletions src/python/pants/backend/native/subsystems/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ python_library(
dependencies=[
'src/python/pants/backend/native/config',
'src/python/pants/backend/native/subsystems/binaries',
'src/python/pants/backend/native/subsystems/utils',
'src/python/pants/engine:rules',
'src/python/pants/engine:selectors',
'src/python/pants/subsystem',
Expand Down
1 change: 1 addition & 0 deletions src/python/pants/backend/native/subsystems/binaries/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
python_library(
dependencies=[
'src/python/pants/backend/native/config',
'src/python/pants/backend/native/subsystems/utils',
'src/python/pants/binaries',
'src/python/pants/engine:rules',
'src/python/pants/engine:selectors',
Expand Down
24 changes: 18 additions & 6 deletions src/python/pants/backend/native/subsystems/binaries/binutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import os

from pants.backend.native.config.environment import Linker, Platform
from pants.backend.native.config.environment import Assembler, Linker
from pants.binaries.binary_tool import NativeTool
from pants.engine.rules import RootRule, rule
from pants.engine.selectors import Select
Expand All @@ -21,20 +21,32 @@ class Binutils(NativeTool):
def path_entries(self):
return [os.path.join(self.select(), 'bin')]

def linker(self, platform):
def assembler(self):
return Assembler(
path_entries=self.path_entries(),
exe_filename='as',
library_dirs=[])

def linker(self):
return Linker(
path_entries=self.path_entries(),
exe_filename='ld',
platform=platform)
library_dirs=[])


@rule(Assembler, [Select(Binutils)])
def get_as(binutils):
return binutils.assembler()


@rule(Linker, [Select(Platform), Select(Binutils)])
def get_ld(platform, binutils):
return binutils.linker(platform)
@rule(Linker, [Select(Binutils)])
def get_ld(binutils):
return binutils.linker()


def create_binutils_rules():
return [
get_as,
get_ld,
RootRule(Binutils),
]
66 changes: 35 additions & 31 deletions src/python/pants/backend/native/subsystems/binaries/gcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@

import os

from pants.backend.native.config.environment import CCompiler, CppCompiler, Platform
from pants.backend.native.subsystems.binaries.binutils import Binutils
from pants.backend.native.config.environment import (CCompiler, CppCompiler, GCCCCompiler,
GCCCppCompiler)
from pants.backend.native.subsystems.utils.parse_search_dirs import ParseSearchDirs
from pants.binaries.binary_tool import NativeTool
from pants.engine.rules import RootRule, rule
from pants.engine.selectors import Select
from pants.util.memo import memoized_property
from pants.util.memo import memoized_method, memoized_property
from pants.util.strutil import create_path_env_var


class GCC(NativeTool):
Expand All @@ -22,46 +24,48 @@ class GCC(NativeTool):

@classmethod
def subsystem_dependencies(cls):
return super(GCC, cls).subsystem_dependencies() + (Binutils.scoped(cls),)
return super(GCC, cls).subsystem_dependencies() + (ParseSearchDirs.scoped(cls),)

@memoized_property
def _binutils(self):
return Binutils.scoped_instance(self)

def _path_entries_for_platform(self, platform):
# GCC requires an assembler 'as' to be on the path. We need to provide this on linux, so we pull
# it from our Binutils package.
as_assembler_path_entries = platform.resolve_platform_specific({
'darwin': lambda: [],
'linux': lambda: self._binutils.path_entries(),
})
all_path_entries = self.path_entries() + as_assembler_path_entries
return all_path_entries
def _parse_search_dirs(self):
return ParseSearchDirs.scoped_instance(self)

def _lib_search_dirs(self, compiler_exe, path_entries):
return self._parse_search_dirs.get_compiler_library_dirs(
compiler_exe,
env={'PATH': create_path_env_var(path_entries)})

@memoized_method
def path_entries(self):
return [os.path.join(self.select(), 'bin')]

def c_compiler(self, platform):
def c_compiler(self):
exe_filename = 'gcc'
path_entries = self.path_entries()
return CCompiler(
path_entries=self._path_entries_for_platform(platform),
exe_filename='gcc',
platform=platform)

def cpp_compiler(self, platform):
path_entries=path_entries,
exe_filename=exe_filename,
library_dirs=self._lib_search_dirs(exe_filename, path_entries),
include_dirs=[])

def cpp_compiler(self):
exe_filename = 'g++'
path_entries = self.path_entries()
return CppCompiler(
path_entries=self._path_entries_for_platform(platform),
exe_filename='g++',
platform=platform)
path_entries=self.path_entries(),
exe_filename=exe_filename,
library_dirs=self._lib_search_dirs(exe_filename, path_entries),
include_dirs=[])


@rule(CCompiler, [Select(Platform), Select(GCC)])
def get_gcc(platform, gcc):
yield gcc.c_compiler(platform)
@rule(GCCCCompiler, [Select(GCC)])
def get_gcc(gcc):
yield GCCCCompiler(gcc.c_compiler())


@rule(CppCompiler, [Select(Platform), Select(GCC)])
def get_gplusplus(platform, gcc):
yield gcc.cpp_compiler(platform)
@rule(GCCCppCompiler, [Select(GCC)])
def get_gplusplus(gcc):
yield GCCCppCompiler(gcc.cpp_compiler())


def create_gcc_rules():
Expand Down
Loading