.NET Core CLI tools and runtime
9160c9ad2be6dfc4a1449714a60327aa034ca992..6b77c8b19f27c16260cfe44ab68298176c0df571
2018-06-07 CentOS Sources
import rh-dotnet21-dotnet-2.1.300-7.el7
6b77c8 diff | tree
4 files added
1 files deleted
375 ■■■■■ changed files
.gitignore 1 ●●●● patch | view | raw | blame | history
.rh-dotnet21-dotnet.metadata 1 ●●●● patch | view | raw | blame | history
README.md 4 ●●●● patch | view | raw | blame | history
SOURCES/check-debug-symbols.py 134 ●●●●● patch | view | raw | blame | history
SPECS/dotnet.spec 235 ●●●●● patch | view | raw | blame | history
.gitignore
New file
@@ -0,0 +1 @@
SOURCES/dotnet-2.1.0.tar.gz
.rh-dotnet21-dotnet.metadata
New file
@@ -0,0 +1 @@
5fb8460cec3086992f5348e8450fa557d12dc99d SOURCES/dotnet-2.1.0.tar.gz
README.md
File was deleted
SOURCES/check-debug-symbols.py
New file
@@ -0,0 +1,134 @@
#!/usr/bin/python2
"""
Check debug symbols are present in shared object and can identify
code.
It starts scanning from a directory and recursively scans all ELF
files found in it for various symbols to ensure all debuginfo is
present and nothing has been stripped.
Usage:
./check-debug-symbols /path/of/dir/to/scan/
Example:
./check-debug-symbols /usr/lib64
"""
# This technique was explained to me by Mark Wielaard (mjw).
import collections
import os
import re
import subprocess
import sys
ScanResult = collections.namedtuple('ScanResult',
                                    'file_name debug_info debug_abbrev file_symbols gnu_debuglink')
def scan_file(file):
    "Scan the provided file and return a ScanResult containing results of the scan."
    # Test for .debug_* sections in the shared object. This is the  main test.
    # Stripped objects will not contain these.
    readelf_S_result = subprocess.check_output(['eu-readelf', '-S', file])
    has_debug_info = any(line for line in readelf_S_result.split('\n') if '] .debug_info' in line)
    has_debug_abbrev = any(line for line in readelf_S_result.split('\n') if '] .debug_abbrev' in line)
    # Test FILE symbols. These will most likely be removed by anyting that
    # manipulates symbol tables because it's generally useless. So a nice test
    # that nothing has messed with symbols.
    def contains_file_symbols(line):
        parts = line.split()
        if len(parts) < 8:
            return False
        return \
            parts[2] == '0' and parts[3] == 'FILE' and parts[4] == 'LOCAL' and parts[5] == 'DEFAULT' and \
            parts[6] == 'ABS' and re.match(r'((.*/)?[-_a-zA-Z0-9]+\.(c|cc|cpp|cxx))?', parts[7])
    readelf_s_result = subprocess.check_output(["eu-readelf", '-s', file])
    has_file_symbols = any(line for line in readelf_s_result.split('\n') if contains_file_symbols(line))
    # Test that there are no .gnu_debuglink sections pointing to another
    # debuginfo file. There shouldn't be any debuginfo files, so the link makes
    # no sense either.
    has_gnu_debuglink = any(line for line in readelf_s_result.split('\n') if '] .gnu_debuglink' in line)
    return ScanResult(file, has_debug_info, has_debug_abbrev, has_file_symbols, has_gnu_debuglink)
def is_elf(file):
    result = subprocess.check_output(['file', file])
    return re.search('ELF 64-bit LSB (?:executable|shared object)', result)
def scan_file_if_sensible(file):
    if is_elf(file):
        # print(file)
        return scan_file(file)
    return None
def scan_dir(dir):
    results = []
    for root, _, files in os.walk(dir):
        for name in files:
            result = scan_file_if_sensible(os.path.join(root, name))
            if result:
                results.append(result)
    return results
def scan(file):
    file = os.path.abspath(file)
    if os.path.isdir(file):
        return scan_dir(file)
    elif os.path.isfile(file):
        return scan_file_if_sensible(file)
def is_bad_result(result):
    return not result.debug_info or not result.debug_abbrev or not result.file_symbols or result.gnu_debuglink
def print_scan_results(results, verbose):
    # print(results)
    for result in results:
        file_name = result.file_name
        found_issue = False
        if not result.debug_info:
            found_issue = True
            print('error: missing .debug_info section in ' + file_name)
        if not result.debug_abbrev:
            found_issue = True
            print('error: missing .debug_abbrev section in ' + file_name)
        if not result.file_symbols:
            found_issue = True
            print('error: missing FILE symbols in ' + file_name)
        if result.gnu_debuglink:
            found_issue = True
            print('error: unexpected .gnu_debuglink section in ' + file_name)
        if verbose and not found_issue:
            print('OK: ', file_name)
def main(args):
    verbose = False
    files = []
    for arg in args:
        if arg == '--verbose' or arg == '-v':
            verbose = True
        else:
            files.append(arg)
    results = []
    for file in files:
        results.extend(scan(file) or [])
    print_scan_results(results, verbose)
    if any(is_bad_result(result) for result in results):
        return 1
    return 0
if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
SPECS/dotnet.spec
New file
@@ -0,0 +1,235 @@
%{?scl:%scl_package dotnet}
%{!?scl:%global pkg_name %{name}}
# lldb doesn't like our nice debug information
%undefine _include_minidebuginfo
%global _find_debuginfo_dwz_opts %{nil}
# Avoid provides/requires from private libraries
%global privlibs             libhostfxr
%global privlibs %{privlibs}|libclrjit
%global privlibs %{privlibs}|libcoreclr
%global privlibs %{privlibs}|libcoreclrtraceptprovider
%global privlibs %{privlibs}|libdbgshim
%global privlibs %{privlibs}|libhostpolicy
%global privlibs %{privlibs}|libmscordaccore
%global privlibs %{privlibs}|libmscordbi
%global privlibs %{privlibs}|libsos
%global privlibs %{privlibs}|libsosplugin
%global __provides_exclude ^(%{privlibs})\\.so
# Remove private libraries and the automatically generated dependency
# on system libcurl package. We require the %%{?scl_prefix}libcurl package
%global __requires_exclude ^(%{privlibs}|libcurl)\\.so
%global sdk_version 2.1.300
%global runtime_version 2.1.0
Name:           %{?scl_prefix}dotnet
Version:        %{sdk_version}
Release:        7%{?dist}
Group:          Development/Languages
Summary:        .NET Core CLI tools and runtime
License:        MIT and ASL 2.0 and BSD
URL:            https://github.com/dotnet/
# The source is generated on a RHEL box via:
# - git clone https://github.com/dotnet/source-build
# - git checkout v2.1.0
# - set environment variables + tweak sources to build
# - ./build-source-tarball.sh dotnet-2.1.0
# - tar cvzf dotnet-2.1.0.tar.gz dotnet-2.1.0
Source0:        dotnet-%{runtime_version}.tar.gz
Source1:        check-debug-symbols.py
ExclusiveArch:  x86_64
BuildRequires:  llvm-toolset-7-clang
BuildRequires:  cmake
BuildRequires:  hostname
BuildRequires:  krb5-devel
BuildRequires:  %{?scl_prefix}libcurl-devel
BuildRequires:  libicu-devel
BuildRequires:  libunwind-devel
BuildRequires:  llvm-toolset-7-lldb-devel
BuildRequires:  llvm-toolset-7-llvm
BuildRequires:  %{?scl_prefix}lttng-ust-devel
BuildRequires:  openssl-devel
BuildRequires:  python2
BuildRequires:  zlib-devel
Requires:       %{name}-sdk-2.1%{?_isa}
%description
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, macOS and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
.NET Core contains a runtime conforming to .NET Standards a set of
framework libraries, an SDK containing compilers and a 'dotnet'
application to drive everything.
%package host
Version:       %{runtime_version}
Summary:        .NET command line launcher
%description host
The .NET Core host is a command line program that runs a standalone
.NET core application or launches the SDK.
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%package runtime-2.1
# Theoretically any version of the host should work
Requires:       %{name}-host
# libicu is dlopen()ed
Requires:       libicu
# libcurl is dlopen()ed
Requires:       %{?scl_prefix}libcurl
Version:        %{runtime_version}
Summary:        NET Core 2.1 runtime
%description runtime-2.1
The .NET Core runtime contains everything needed to run .NET Core applications.
It includes a high performance Virtual Machine as well as the framework
libraries used by .NET Core applications.
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%package sdk-2.1
Version:        %{sdk_version}
Summary:        .NET Core 2.1 Software Development Kit
Provides:       %{name}-sdk-2.1.3xx = %{version}-%{release}
Requires:       %{name}-runtime-2.1%{?_isa}
%description sdk-2.1
The .NET Core SDK is a collection of command line applications to
create, build, publish and run .NET Core applications.
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%prep
%setup -q -n %{pkg_name}-%{runtime_version}
# Disable warnings
sed -i 's|skiptests|skiptests ignorewarnings|' repos/coreclr.proj
# Fix bad hardcoded path in build
sed -i 's|/usr/share/dotnet|%{_libdir}/%{pkg_name}|' src/core-setup/src/corehost/common/pal.unix.cpp
sed -i 's|git apply --ignore-whitespace --whitespace=nowarn|patch -p1 -i|' repos/dir.targets
%build
%{?scl:scl enable %scl llvm-toolset-7 - << \EOF}
set -xe
export LIBRARY_PATH="%{_libdir}"
export LLVM_HOME=/opt/rh/llvm-toolset-7/root/usr
export CMAKE_PREFIX_PATH="%{_prefix}"
./build.sh /v:diag
%{?scl:EOF}
%install
install -d -m 0755 %{buildroot}%{_libdir}/%{pkg_name}/
ls bin/x64/Release
tar xf bin/x64/Release/dotnet-sdk-%{sdk_version}-*.tar.gz -C %{buildroot}%{_libdir}/%{pkg_name}/
# Fix permissions on files
find %{buildroot}%{_libdir}/%{pkg_name}/ -type f -name '*.props' -exec chmod -x {} \;
find %{buildroot}%{_libdir}/%{pkg_name}/ -type f -name '*.targets' -exec chmod -x {} \;
find %{buildroot}%{_libdir}/%{pkg_name}/ -type f -name '*.dll' -exec chmod -x {} \;
find %{buildroot}%{_libdir}/%{pkg_name}/ -type f -name '*.pubxml' -exec chmod -x {} \;
install -dm 755 %{buildroot}/%{_root_datadir}/bash-completion/completions
# dynamic completion needs the file to be named the same as the base command
install src/cli/scripts/register-completions.bash %{buildroot}/%{_root_datadir}/bash-completion/completions/dotnet
# TODO: the zsh completion script needs to be ported to use #compdef
#install -dm 755 %%{buildroot}/%%{_datadir}/zsh/site-functions
#install src/cli/scripts/register-completions.zsh %%{buildroot}/%%{_datadir}/zsh/site-functions/_dotnet
install -d -m 0755 %{buildroot}%{_bindir}
ln -s %{_libdir}/%{pkg_name}/dotnet %{buildroot}%{_bindir}/
install -d -m 0755 %{buildroot}%{_mandir}/man1/
find -iname 'dotnet*.1' -type f -exec cp {} %{buildroot}%{_mandir}/man1/ \;
# Check debug symbols in all elf objects. This is not in %%check
# because native binaries are stripped by rpm-build after %%install.
# So we need to do this check earlier.
echo "Testing build results for debug symbols..."
%{SOURCE1} -v %{buildroot}%{_libdir}/%{pkg_name}/
%check
%{buildroot}%{_libdir}/%{pkg_name}/dotnet --info
%files
# empty package useful for dependencies
%files host
%dir %{_libdir}/%{pkg_name}
%{_libdir}/%{pkg_name}/dotnet
%{_libdir}/%{pkg_name}/host
%{_bindir}/dotnet
%doc %{_libdir}/%{pkg_name}/LICENSE.txt
%doc %{_libdir}/%{pkg_name}/ThirdPartyNotices.txt
%doc %{_mandir}/man1/dotnet.1.gz
%files runtime-2.1
%dir %{_libdir}/%{pkg_name}/shared
%dir %{_libdir}/%{pkg_name}/shared/Microsoft.NETCore.App
%{_libdir}/%{pkg_name}/shared/Microsoft.NETCore.App/%{runtime_version}
%files sdk-2.1
%dir %{_libdir}/%{pkg_name}/sdk
%{_libdir}/%{pkg_name}/sdk/%{sdk_version}
%doc %{_mandir}/man1/dotnet-*.1.gz
# shell completions are currently only picked up from %%{_root_datadir}
%dir %{_root_datadir}/bash-completion
%dir %{_root_datadir}/bash-completion/completions
%{_root_datadir}/bash-completion/completions/dotnet
%changelog
* Wed May 30 2018 Omair Majid <omajid@redhat.com> - 2.1.300-7
- Explicitly require a modified libcurl
* Tue May 29 2018 Omair Majid <omajid@redhat.com> - 2.1.300-6
- Install bash completions in %%{_root_datadir}
* Mon May 28 2018 Omair Majid <omajid@redhat.com> - 2.1.300-5
- Add provides for dotnet-sdk-2.1.3xx
* Mon May 28 2018 Omair Majid <omajid@redhat.com> - 2.1.300-4
- Remove patch for ASP.NET Core templates. No longer needed for 2.1.
* Fri May 25 2018 Omair Majid <omajid@redhat.com> - 2.1.300-3
- Remove net46 symlink
* Thu May 24 2018 Omair Majid <omajid@redhat.com> - 2.1.300-2
- Rebuild to pick up updated dependencies
* Thu May 24 2018 Omair Majid <omajid@redhat.com> - 2.1.300-1
- New package. Import from Fedora (DotNet SIG package).