Example #1
0
    def test_hello_cpp_clangpp(self):

        scheduler_request_specs = [
            # We need GCC to provide libstdc++.so.6, which clang needs to run on Linux.
            (self.toolchain, GCCCppCompiler),
            (self.toolchain, LLVMCppCompiler),
            (self.toolchain, Linker),
        ]

        with self._hello_world_source_environment(
                'hello.cpp',
                contents="""
#include <iostream>

int main() {
  std::cout << "I C the world, ++ more!" << std::endl;
}
""",
                scheduler_request_specs=scheduler_request_specs) as products:

            gpp_wrapper, clangpp_wrapper, linker = products
            gpp = gpp_wrapper.cpp_compiler
            clangpp = clangpp_wrapper.cpp_compiler

            # FIXME(#5951): we should be matching the linker to the compiler here, instead of trying to
            # use the same linker for everything. This is a temporary workaround.
            linker_with_clangpp_workaround = Linker(
                path_entries=(clangpp.path_entries + linker.path_entries),
                exe_filename=clangpp.exe_filename,
                library_dirs=(gpp.library_dirs + linker.library_dirs +
                              clangpp.library_dirs))

            self._do_compile_link(clangpp, linker_with_clangpp_workaround,
                                  'hello.cpp', 'hello_clangpp',
                                  "I C the world, ++ more!")
Example #2
0
 def linker(self, platform):
   return Linker(
     path_entries=self.path_entries(),
     # FIXME(#5951): This actually links correctly for both C and C++ sources -- there should
     # probably be some testing to ensure this is correct in CI as well.
     exe_filename='clang++',
     platform=platform)
Example #3
0
 def linker(self, platform):
     return Linker(path_entries=self.path_entries,
                   exe_filename=platform.resolve_platform_specific(
                       self._PLATFORM_SPECIFIC_LINKER_NAME),
                   library_dirs=[],
                   linking_library_dirs=[],
                   extra_args=[])
Example #4
0
 def linker(self):
   return Linker(
     path_entries=self.path_entries(),
     exe_filename='ld',
     library_dirs=[],
     linking_library_dirs=[],
     extra_args=[])
Example #5
0
 def linker(self) -> Linker:
     return Linker(
         path_entries=self.path_entries(),
         exe_filename="ld",
         runtime_library_dirs=(),
         linking_library_dirs=(),
         extra_args=(),
         extra_object_files=(),
     )
Example #6
0
 def linker(self):
     return Linker(
         path_entries=self.path_entries(),
         exe_filename='ld',
         runtime_library_dirs=[],
         linking_library_dirs=[],
         extra_args=[MIN_OSX_VERSION_ARG],
         extra_object_files=[],
     )
Example #7
0
 def linker(self, platform: Platform) -> Linker:
   return Linker(
     path_entries=self.path_entries,
     exe_filename=match(platform, {
       Platform.darwin: "ld64.lld",
       Platform.linux: "lld",
     }),
     runtime_library_dirs=(),
     linking_library_dirs=(),
     extra_args=(),
     extra_object_files=(),
   )
Example #8
0
 def linker(self, platform):
     return Linker(
         path_entries=self.path_entries,
         exe_filename=platform.match({
             Platform.darwin: "ld64.lld",
             Platform.linux: "lld",
         }),
         library_dirs=[],
         linking_library_dirs=[],
         extra_args=[],
         extra_object_files=[],
     )
Example #9
0
 def linker(self, platform):
     return Linker(
         path_entries=self.path_entries,
         exe_filename=platform.resolve_for_enum_variant({
             'darwin': 'ld64.lld',
             'linux': 'lld',
         }),
         library_dirs=[],
         linking_library_dirs=[],
         extra_args=[],
         extra_object_files=[],
     )
Example #10
0
def select_llvm_c_toolchain(platform, native_toolchain):
    provided_clang = yield Get(CCompiler, LLVM, native_toolchain._llvm)

    # These arguments are shared across platforms.
    llvm_c_compiler_args = [
        '-x',
        'c',
        '-std=c11',
        '-nobuiltininc',
    ]

    if platform.normalized_os_name == 'darwin':
        xcode_clang = yield Get(CCompiler, XCodeCLITools,
                                native_toolchain._xcode_cli_tools)
        working_c_compiler = CCompiler(
            path_entries=(provided_clang.path_entries +
                          xcode_clang.path_entries),
            exe_filename=provided_clang.exe_filename,
            library_dirs=(provided_clang.library_dirs +
                          xcode_clang.library_dirs),
            include_dirs=(provided_clang.include_dirs +
                          xcode_clang.include_dirs),
            extra_args=(llvm_c_compiler_args + xcode_clang.extra_args))
    else:
        gcc_install = yield Get(GCCInstallLocationForLLVM, GCC,
                                native_toolchain._gcc)
        provided_gcc = yield Get(CCompiler, GCC, native_toolchain._gcc)
        working_c_compiler = CCompiler(
            path_entries=provided_clang.path_entries,
            exe_filename=provided_clang.exe_filename,
            # We need g++'s version of the GLIBCXX library to be able to run, unfortunately.
            library_dirs=(provided_gcc.library_dirs +
                          provided_clang.library_dirs),
            include_dirs=provided_gcc.include_dirs,
            extra_args=(llvm_c_compiler_args + gcc_install.as_clang_argv))

    base_linker_wrapper = yield Get(BaseLinker, NativeToolchain,
                                    native_toolchain)
    base_linker = base_linker_wrapper.linker
    libc_dev = yield Get(LibcDev, NativeToolchain, native_toolchain)
    working_linker = Linker(
        path_entries=(base_linker.path_entries +
                      working_c_compiler.path_entries),
        exe_filename=working_c_compiler.exe_filename,
        library_dirs=(base_linker.library_dirs +
                      working_c_compiler.library_dirs),
        linking_library_dirs=(base_linker.linking_library_dirs +
                              libc_dev.get_libc_dirs(platform)),
        extra_args=base_linker.extra_args)

    yield LLVMCToolchain(CToolchain(working_c_compiler, working_linker))
Example #11
0
def select_gcc_cpp_toolchain(platform, native_toolchain):
    provided_gpp = yield Get(CppCompiler, GCC, native_toolchain._gcc)

    # GCC needs an assembler, so we provide that (platform-specific) tool here.
    assembler = yield Get(Assembler, NativeToolchain, native_toolchain)

    if platform.normalized_os_name == 'darwin':
        # GCC needs access to some headers that are only provided by the XCode toolchain
        # currently (e.g. "_stdio.h"). These headers are unlikely to change across versions, so this is
        # probably safe.
        # TODO: we should be providing all of these (so we can eventually phase out XCodeCLITools
        # entirely).
        xcode_clangpp = yield Get(CppCompiler, XCodeCLITools,
                                  native_toolchain._xcode_cli_tools)
        new_include_dirs = xcode_clangpp.include_dirs + provided_gpp.include_dirs
    else:
        new_include_dirs = provided_gpp.include_dirs

    working_cpp_compiler = CppCompiler(
        path_entries=(provided_gpp.path_entries + assembler.path_entries),
        exe_filename=provided_gpp.exe_filename,
        library_dirs=provided_gpp.library_dirs,
        include_dirs=new_include_dirs,
        extra_args=([
            '-x',
            'c++',
            '-std=c++11',
            '-nostdinc++',
        ]))

    base_linker_wrapper = yield Get(BaseLinker, NativeToolchain,
                                    native_toolchain)
    base_linker = base_linker_wrapper.linker
    libc_dev = yield Get(LibcDev, NativeToolchain, native_toolchain)
    working_linker = Linker(
        path_entries=(working_cpp_compiler.path_entries +
                      base_linker.path_entries),
        exe_filename=working_cpp_compiler.exe_filename,
        library_dirs=(base_linker.library_dirs +
                      working_cpp_compiler.library_dirs),
        linking_library_dirs=(base_linker.linking_library_dirs +
                              libc_dev.get_libc_dirs(platform)),
        extra_args=base_linker.extra_args)

    yield GCCCppToolchain(CppToolchain(working_cpp_compiler, working_linker))
Example #12
0
def select_linker(platform, native_toolchain):
    # TODO(#5933): make it possible to yield Get with a non-static
    # subject type and use `platform.resolve_platform_specific()`, something like:
    # linker = platform.resolve_platform_specific({
    #   'darwin': lambda: Get(Linker, XCodeCLITools, native_toolchain._xcode_cli_tools),
    #   'linux': lambda: Get(Linker, Binutils, native_toolchain._binutils),
    # })
    if platform.normalized_os_name == 'darwin':
        # TODO(#5663): turn this into LLVM when lld works.
        linker = yield Get(Linker, XCodeCLITools,
                           native_toolchain._xcode_cli_tools)
        libc_dirs = []
    else:
        linker = yield Get(Linker, Binutils, native_toolchain._binutils)
        libc_dirs = [native_toolchain._libc_dev.host_libc.get_lib_dir()]

    # NB: We need to link through a provided compiler's frontend, and we need to know where all the
    # compiler's libraries/etc are, so we set the executable name to the C++ compiler, which can find
    # its own set of C++-specific files for the linker if necessary. Using e.g. 'g++' as the linker
    # appears to produce byte-identical output when linking even C-only object files, and also
    # happens to work when C++ is used.
    gcc_c_compiler = yield Get(GCCCCompiler, NativeToolchain, native_toolchain)
    c_compiler = gcc_c_compiler.c_compiler
    gcc_cpp_compiler = yield Get(GCCCppCompiler, NativeToolchain,
                                 native_toolchain)
    cpp_compiler = gcc_cpp_compiler.cpp_compiler

    # NB: If needing to create an environment for process invocation that could use either a compiler
    # or a linker (e.g. when we compile native code from `python_dist()`s), use the environment from
    # the linker object (in addition to any further customizations), which has the paths from the C
    # and C++ compilers baked in.
    # FIXME(#5951): we need a way to compose executables more hygienically.
    linker = Linker(
        path_entries=(c_compiler.path_entries + cpp_compiler.path_entries +
                      linker.path_entries),
        exe_filename=cpp_compiler.exe_filename,
        library_dirs=(libc_dirs + c_compiler.library_dirs +
                      cpp_compiler.library_dirs + linker.library_dirs))

    yield linker
Example #13
0
def select_llvm_cpp_toolchain(platform, native_toolchain):
    provided_clangpp = yield Get(CppCompiler, LLVM, native_toolchain._llvm)

    # These arguments are shared across platforms.
    llvm_cpp_compiler_args = [
        '-x',
        'c++',
        '-std=c++11',
        # This mean we don't use any of the headers from our LLVM distribution's C++ stdlib
        # implementation, or any from the host system. Instead, we use include dirs from the
        # XCodeCLITools or GCC.
        '-nobuiltininc',
        '-nostdinc++',
    ]

    if platform.normalized_os_name == 'darwin':
        xcode_clang = yield Get(CppCompiler, XCodeCLITools,
                                native_toolchain._xcode_cli_tools)
        working_cpp_compiler = CppCompiler(
            path_entries=(provided_clangpp.path_entries +
                          xcode_clang.path_entries),
            exe_filename=provided_clangpp.exe_filename,
            library_dirs=(provided_clangpp.library_dirs +
                          xcode_clang.library_dirs),
            include_dirs=(provided_clangpp.include_dirs +
                          xcode_clang.include_dirs),
            # On OSX, this uses the libc++ (LLVM) C++ standard library implementation. This is
            # feature-complete for OSX, but not for Linux (see https://libcxx.llvm.org/ for more info).
            extra_args=(llvm_cpp_compiler_args + xcode_clang.extra_args))
        linking_library_dirs = []
        linker_extra_args = []
    else:
        gcc_install = yield Get(GCCInstallLocationForLLVM, GCC,
                                native_toolchain._gcc)
        provided_gpp = yield Get(CppCompiler, GCC, native_toolchain._gcc)
        working_cpp_compiler = CppCompiler(
            path_entries=provided_clangpp.path_entries,
            exe_filename=provided_clangpp.exe_filename,
            # We need g++'s version of the GLIBCXX library to be able to run, unfortunately.
            library_dirs=(provided_gpp.library_dirs +
                          provided_clangpp.library_dirs),
            # NB: we use g++'s headers on Linux, and therefore their C++ standard library.
            include_dirs=provided_gpp.include_dirs,
            extra_args=(llvm_cpp_compiler_args + gcc_install.as_clang_argv))
        linking_library_dirs = provided_gpp.library_dirs + provided_clangpp.library_dirs
        # Ensure we use libstdc++, provided by g++, during the linking stage.
        linker_extra_args = ['-stdlib=libstdc++']

    libc_dev = yield Get(LibcDev, NativeToolchain, native_toolchain)
    base_linker_wrapper = yield Get(BaseLinker, NativeToolchain,
                                    native_toolchain)
    base_linker = base_linker_wrapper.linker
    working_linker = Linker(
        path_entries=(base_linker.path_entries +
                      working_cpp_compiler.path_entries),
        exe_filename=working_cpp_compiler.exe_filename,
        library_dirs=(base_linker.library_dirs +
                      working_cpp_compiler.library_dirs),
        linking_library_dirs=(base_linker.linking_library_dirs +
                              linking_library_dirs +
                              libc_dev.get_libc_dirs(platform)),
        extra_args=(base_linker.extra_args + linker_extra_args))

    yield LLVMCppToolchain(CppToolchain(working_cpp_compiler, working_linker))
Example #14
0
 def linker(self, platform):
     return Linker(path_entries=self.path_entries(),
                   exe_filename='ld',
                   platform=platform)
Example #15
0
 def linker(self, platform):
     return Linker(path_entries=self.path_entries(),
                   exe_filename=platform.resolve_platform_specific(
                       self._PLATFORM_SPECIFIC_LINKER_NAME),
                   platform=platform)