Skip to content

centos8 rpm spec #27

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

Merged
merged 2 commits into from
Oct 1, 2021
Merged

centos8 rpm spec #27

merged 2 commits into from
Oct 1, 2021

Conversation

tomerd
Copy link
Contributor

@tomerd tomerd commented Sep 30, 2021

motivation: rpm installer for centos8

changes: initial setup: spec, patches, driver script and docker for centos 8

Open Issues / TODO

  • the swift release version should be an argument
  • the versions of source packages are no pinned to the swift release version (eg yams) should come from an external file, likely one per swift release version
  • the list of build requirements (BuildRequires) and especially requirements (Requires) should come from an external file, likely one per swift release version (which we can use it to also drive documentation)
  • I put this spec in the "dev" directory to indicate this is the full toolchain, we need to all have a spec for the "runtime" version that has all the swift programs runtime dependencies without the toolchain itself, ie for running swift programs. not sure if we want one spec file that produces both, or separate ones. so tbd

motivation: rpm installer for centos8

changes: initial setup: spec, patches, driver script and docker for centos 8
@tomerd tomerd requested a review from shahmishal September 30, 2021 22:36
@@ -0,0 +1,23 @@

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this patch for CentOS 8?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally I would like to get to zero patches. this one specifically does two things in build-presets:

  1. uses the system ninja instead building it from source. we can also change the spec to download ninja and build it from source if preferable
  2. disables "test-installable-package", which I took from the fedora spec. not sure why it was needed there. @tachoknight?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomerd I'm trying to get Fedora down to no patches as well. I have this PR which I called buildbot_linux_fedora,no_test, but maybe it would be better to make it more generic to RPM-based distros? The test-installable-package was the source of a lot of errors with Python, I'm trying a build with it enabled to see if it's still an issue.

Copy link
Contributor

@tachoknight tachoknight Oct 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally I would like to get to zero patches. this one specifically does two things in build-presets:

  1. uses the system ninja instead building it from source. we can also change the spec to download ninja and build it from source if preferable

I had to do this for CMake under CentOS 8 for awhile; I have an example if you'd like to see how to do it in a spec file here.

  1. disables "test-installable-package", which I took from the fedora spec. not sure why it was needed there. @tachoknight?

I tested the latest Swift-5.5 snapshot with test-installable-package enabled and it worked, so this is no longer necessary to be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uses the system ninja instead building it from source. we can also change the spec to download ninja and build it from source if preferable

@shahmishal is there a reason not to use the system ninja when it is available?

Copy link
Contributor Author

@tomerd tomerd Oct 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disables "test-installable-package", which I took from the fedora spec. not sure why it was needed there. @tachoknight?
I tested the latest Swift-5.5 snapshot with test-installable-package enabled and it worked, so this is no longer necessary to be removed.

@tachoknight should we update/remove the patch then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uses the system ninja instead building it from source. we can also change the spec to download ninja and build it from source if preferable
@shahmishal is there a reason not to use the system ninja when it is available?

I dont see a problem in using the system ninja if it's available.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disables "test-installable-package", which I took from the fedora spec. not sure why it was needed there. @tachoknight?
I tested the latest Swift-5.5 snapshot with test-installable-package enabled and it worked, so this is no longer necessary to be removed.
@tachoknight should we update/remove the patch then?

I think we should remove the patch, and add support spec file to clone ninja.

@tomerd
Copy link
Contributor Author

tomerd commented Sep 30, 2021

@discogestalt
Copy link

What I like to do is have the build script write out the spec file, that gives you the ability to set the versions, requirements list, etc. as options to the script, either as arguments or CI environment vars. Below is an example I was working on for packaging under CentOS7 or 8. The swift build was handled by a separate shell script, generating the full tar ball, and then this script was called to write out the spec file and do the rpm build. I was experimenting with package separation, so this version builds swift, swift-foundation, swift-libdispatch, swift-libicu and swift-xctest packages, which is overkill. $PKG_VERSION and $PKG_RELEASE would be set in the environment. $BUILD_BASE is set by the rpmbuild process.

Build requirement lists could easily be read in from a separate text file as well.

#!/bin/bash

set -ex

EL=$(for i in $(cat /etc/redhat-release); do echo $i | grep '^[78]' | cut -d'.' -f1; done)
if [[ -z $EL ]]; then
    echo "Packaging requires Enterprise Linux v7 or v8"
    exit 1
fi

REQUIRES="libatomic libedit libstdc++ libxml2 ncurses-libs"

PKG_SPEC="${PKG_VERSION}-${PKG_RELEASE}"

(cat <<EOF
%define isEL7 %( if [[ "${EL}" = "7" ]]; then echo "1"; else echo "0"; fi )
%global _enable_debug_package 0
%global debug_package %{nil}
%global __os_install_post /usr/lib/rpm/brp-compress %{nil}
%undefine _missing_build_ids_terminate_build


Name:		swift
Version:	${PKG_VERSION}
Release:	${PKG_RELEASE}%{?dist}
Summary:	Swift -- Apple Swift Language
Group:		Development/Languages

License:	Apache 2.0
URL:		https://swift.org/
Source:		https://github.com/apple/swift.git

AutoReqProv:	no
Requires:	swift-foundation = ${PKG_SPEC}%{?dist}
Requires:	swift-libdispatch = ${PKG_SPEC}%{?dist}
Requires:	swift-libicu = ${PKG_SPEC}%{?dist}
Requires:	libstdc++-devel zlib-devel
%if %isEL7
Requires:	epel-release centos-release-scl sclo-git25-git devtoolset-8 llvm-toolset-7
%else
Requires:	gcc glibc-devel python2-libs python36
%endif

%description
Swift Programming Language


%package foundation
Summary: 	Swift Core Foundation Library
Group:		Development/Libraries
AutoReqProv:	no
Requires:	${REQUIRES}
%if %isEL7
Requires:	gnutls libidn2 libmetalink libnghttp2 libssh2 openldap openssl-libs krb5-libs
%endif
%description foundation
Swift Core Foundation Library


%package libdispatch
Summary: 	Swift Core Libdispatch
Group:		Development/Libraries
AutoReqProv:	no
%description libdispatch
Swift Core Libdispatch


%package libicu
Summary:	Swift International Components For Unicode
Group:		Development/Libraries
AutoReqProv:	no
%description libicu
Swift International Components For Unicode


%package xctest
Summary:	Swift Common Test Framework
Group:		Development/Libraries
AutoReqProv:	no
%description xctest
Swift Common Test Framework


%prep


%build


%install
cd %{buildroot}
tar xzf %{_builddir}/swift-${PKG_VERSION}-${PKG_RELEASE}.el${EL}.tar.gz


%clean
rm -rf %{buildroot}


%files
%docdir /usr/share/man
/usr/bin/*
/usr/include/*
/usr/lib/clang
/usr/lib/liblldb*
/usr/lib/libIndexStore*
/usr/lib/libsourcekitdInProc*
/usr/lib/libswiftDemangle*
/usr/lib/swift/Block
/usr/lib/swift/CFURLSessionInterface
/usr/lib/swift/CFXMLInterface
/usr/lib/swift/clang
/usr/lib/swift/CoreFoundation
/usr/lib/swift/dispatch
/usr/lib/swift/FrameworkABIBaseline
/usr/lib/swift/_InternalSwiftSyntaxParser
/usr/lib/swift/linux/lib_InternalSwiftSyntaxParser*
/usr/lib/swift/linux/libswiftRemoteMirror*
/usr/lib/swift/linux/libswift_Differentiation.so
/usr/lib/swift/linux/x86_64
/usr/lib/swift/migrator
/usr/lib/swift/os
/usr/lib/swift/pm
/usr/lib/swift/shims
/usr/lib/swift_static
/usr/local/include/indexstore
/usr/share/doc/swift/diagnostics
/usr/share/man/man1/swift*
/usr/share/swift


%files foundation
%docdir /usr/share/man
/usr/lib/swift/linux/libFoundation*
/usr/lib/swift/linux/libswiftCore*
/usr/lib/swift/linux/libswiftGlibc*
/usr/lib/swift/linux/libswiftSwiftOnoneSupport*


%files libdispatch
/usr/lib/libBlocksRuntime.so
/usr/lib/libdispatch.so
/usr/lib/swift/linux/libBlocksRuntime.so
/usr/lib/swift/linux/libdispatch.so
/usr/lib/swift/linux/libswiftDispatch.so


%files libicu
/usr/lib/swift/linux/libicu*
/usr/share/icuswift


%files xctest
/usr/lib/swift/linux/x86_64/XCTest*
/usr/lib/swift/linux/libXCTest.so


%post
if [[ ! -e /usr/lib64/libgcc_s.so ]]; then
    (cat <<LGCC
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library.  */
GROUP ( libgcc_s.so.1 -lgcc )
LGCC
) > /usr/lib64/libgcc_s.so || :
fi
ln -sf /usr/lib64/libstdc++.so.6.0.?? /usr/lib64/libstdc++.so || :
sed -i -e 's/\*__block/\*__libc_block/g' /usr/include/unistd.h || :
/usr/sbin/ldconfig || :


%post foundation
/usr/sbin/ldconfig || :

EOF
) > ~/rpmbuild/SPECS/swift.spec

rm -rf ${BUILD_BASE}/BUILD/swift-install

cd
rpmbuild -v -bb ${BUILD_BASE}/SPECS/swift.spec

exit $?

@tachoknight
Copy link
Contributor

  • I put this spec in the "dev" directory to indicate this is the full toolchain, we need to all have a spec for the "runtime" version that has all the swift programs runtime dependencies without the toolchain itself, ie for running swift programs. not sure if we want one spec file that produces both, or separate ones. so tbd

I initially had a swift-lang-runtime that packaged only the libs necessary to run a Swift program. It was removed at the same time I moved the installation directory to /usr/libexec/swift to prevent lib collisions with the default LLVM and LLDB.

@tachoknight
Copy link
Contributor

What I like to do is have the build script write out the spec file, that gives you the ability to set the versions, requirements list, etc. as options to the script, either as arguments or CI environment vars.

I've been working on a script to do just that; was behind on some of the other packages which I had to track down. One thing to note is that this can't be used as part of the "official" RPM build for the Fedora repo as the spec file already needs to exist in its final form when building the binary RPM.

My thought is to use the script to update the spec file and run the build (see the script I currently use to build Swift; the spec file that is contained in the SRPM file is what can then be submitted to Koji (the Fedora build system) to build the final package.

@tomerd
Copy link
Contributor Author

tomerd commented Oct 1, 2021

What I like to do is have the build script write out the spec file, that gives you the ability to set the versions, requirements list, etc. as options to the script, either as arguments or CI environment vars.
I've been working on a script to do just that; was behind on some of the other packages which I had to track down. One thing to note is that this can't be used as part of the "official" RPM build for the Fedora repo as the spec file already needs to exist in its final form when building the binary RPM.

I've been working on a script to do just that; was behind on some of the other packages which I had to track down. One thing to note is that this can't be used as part of the "official" RPM build for the Fedora repo as the spec file already needs to exist in its final form when building the binary RPM

how about we do this in stages? first we get manually crafted specs that work across the platforms we want to support: fedora, centos, Amazon Linux, debian and ubuntu. then we optimize further by adding a script that generate the specs for future iterations. this way we can make progress on all the other downstream tooling (CI, signing, distribution) without getting bugged down with the optimization. @shahmishal wdyt?

Comment on lines +13 to +14
License: ASL 2.0 and Unicode
URL: https://swift.org
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
License: ASL 2.0 and Unicode
URL: https://swift.org
License: Apache 2.0
URL: https://swift.org

I think we should update the License to Apache 2.0.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will have to do the same for Fedora spec file.

@shahmishal
Copy link
Member

Going to merge this, and we can make improvements to the scripts before officially releasing the rpm installer.

@shahmishal shahmishal merged commit 55a6039 into swiftlang:main Oct 1, 2021
@futurejones
Copy link
Contributor

@tomerd @shahmishal I am trying to understand the logic of merging this pull request when the submitted code is incorrect and there are many other aspects which are still being discussed.
@shahmishal as you have pointed out it has the incorrect license but you are still going ahead with the merge.
It actually doesn't make much sense even having a centos8 version as swift is already available to centos8 via https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm.
As https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm is a dependency requirement for swift any attempt to install a separate centos8 version from another source will conflict with the package already available.

Another question is why we are reinventing the wheel?
We already have official releases of centos8 - https://swift.org/builds/swift-5.5-release/centos8/swift-5.5-RELEASE/swift-5.5-RELEASE-centos8.tar.gz
It makes far more sense to create the rpm packages using the official release .tar.gz files.
This can easily be done with available tools, no need for dockerfiles and multiple os/system ci servers. Everything can be done on a single linux build machine, no mater what os or arch type the package is.

Here is an example of a Jenkinsfile I am using to build developer snapshots deb packages from the official Swift source for the Swift Community Apt Repository
This example is for deb packages but rpm's can be created just as easily.

// Jenkins Pipeline - swift deb/rpm packager - swift.org amd64
// ubuntu 20.04 main-branch snapshot

pipeline {
   agent { label 'swiftaltra' }

   environment {
        PKG_ITERATION='2021-09-07-a'
        PKG_VERSION='5.6'
        DIST = 'ubuntu'
        VER_NAME = 'focal'
        VER_NUM='20.04'
        SWIFT_URL="https://swift.org/builds/development/ubuntu2004/swift-DEVELOPMENT-SNAPSHOT-${PKG_ITERATION}/swift-DEVELOPMENT-SNAPSHOT-${PKG_ITERATION}-ubuntu20.04.tar.gz"
   }
   stages {
      stage('Clean Workspace') {
         steps {
            echo 'Cleaning Workspace'
            cleanWs()
            script {
                    currentBuild.displayName = "swift-DEVELOPMENT-SNAPSHOT-${PKG_ITERATION}"
                }
         }
      }
      stage('Get Swift Toolchain') {
         steps {
            echo 'Getting Swift'
            sh 'curl -fsSL "$SWIFT_URL" -o swift.tar.gz'
            sh 'ls'
         }
      }
      stage('Clean Package') {
          steps {
            sh 'tar -xzf swift.tar.gz --strip-components=1'
            sh 'rm usr/lib/python3/dist-packages/six.py'
          }
      }
      stage('Package DEB') {
          steps {
            echo "building deb"
            sh "rm *.deb || true"
            sh "export XZ_DEFAULTS='-9 -T0'; fpm \
               -s dir \
               -t deb \
               -a amd64 \
               --name swiftlang \
               --version ${PKG_VERSION} \
               --iteration ${PKG_ITERATION}-${DIST}-${VER_NAME} \
               -d binutils \
               -d git \
               -d gnupg2 \
               -d libc6-dev \
               -d libcurl4 \
               -d libedit2 \
               -d libgcc-9-dev \
               -d libpython3.8 \
               -d libsqlite3-0 \
               -d libstdc++-9-dev \
               -d libxml2 \
               -d libz3-dev \
               -d pkg-config \
               -d tzdata \
               -d zlib1g-dev \
               --replaces clang \
               --replaces clang-10 \
               --replaces libicu-dev \
               --replaces lld \
               --replaces lldb \
               --replaces llvm \
               --maintainer 'Swift Infrastructure <[email protected]>' \
               --deb-priority optional \
               --url 'https://swift.org' \
               --description 'The Swift Programming Language.' \
               --license 'Apache License Version 2.0' \
               --deb-no-default-config-files \
               --deb-compression xz \
               usr"
         }
      }
      stage('Upload to Server') {
         steps {
            echo 'uploading to repository'
            sh "scp *.deb   [email protected]:/home/futurejones/debs/new-snapshots/${DIST}/${VER_NAME}/"
         }
      }
   }
}

This can be done for all the official Swift releases rpm or deb packages.
1 - pull official release file from swift.org
2 - build rpm or deb package
3 - upload to distribution point

Another huge advantage of this approach is the build time. No need to build the entire swift toolchain which can take hours, a deb or rpm package can be built in minutes.

@shahmishal
Copy link
Member

@shahmishal as you have pointed out it has the incorrect license but you are still going ahead with the merge.

This is now resolved with these two PRs: #29 #28

Another question is why we are reinventing the wheel?
We already have official releases of centos8 - https://swift.org/builds/swift-5.5-release/centos8/swift-5.5-RELEASE/swift-5.5-RELEASE-centos8.tar.gz
It makes far more sense to create the rpm packages using the official release .tar.gz files.
This can easily be done with available tools, no need for dockerfiles and multiple os/system ci servers. Everything can be done on a single linux build machine, no mater what os or arch type the package is.

@tomerd @tachoknight Do you see any issue with this? It would help reduce the resource on CI.

@futurejones I might have miss understood, but I thought the official spec requires building the package from source.

This example is for deb packages but rpm's can be created just as easily.

Thanks for sharing the Jenkinsfile.

@tachoknight
Copy link
Contributor

@futurejones I might have miss understood, but I thought the official spec requires building the package from source.

Yes, that is correct. @futurejones, the official Fedora/EPEL RPMS are always built from source on their servers; binary blobs are not allowed to be packaged; the only thing that can be submitted for building is the .spec file and whatever additional non-binary files are needed to build the package.

@futurejones
Copy link
Contributor

@tomerd @shahmishal

the official Fedora/EPEL RPMS are always built from source on their servers;

Yes @tachoknight is correct but as far as I was aware the purpose of building the rpm/deb packages was to host them on on an official Swift.org package repository. Not submit them to Ubuntu, Debian, Redhat etc. for inclusion their official repos.
If the packages are being selfhosted in our own repository or a repository like https://packagecloud.io/ there is no need to use spec files. The rpm files are uploaded directly to the repository.

For example Swift for Centos8/AArch64 which is available on the Swift-Arm Community repository.
https://packagecloud.io/swift-arm/release/packages/el/8/swiftlang-5.4.1-6_centos_8.aarch64.rpm
was built using a Jenkinsfile similar to the above file.

@tachoknight
Copy link
Contributor

... Not submit them to Ubuntu, Debian, Redhat etc. for inclusion their official repos.

My goal is to have this repo represent all the files necessary to build the official RPM. It would be a poor user experience that the versions of Swift differ between the self-hosted and repo-based locations.

@futurejones
Copy link
Contributor

@tachoknight I am not sure I understand, I was referring the method of building the rpm file not which version of swift is hosted. If you build the rpm from the official swift-5.5-release.tar.gz file or from the source code with a spec file both rpms will install the identical version of swift. By self-hosted I meant hosted officially by Swift.org on their servers.

@tomerd
Copy link
Contributor Author

tomerd commented Oct 3, 2021

the motivation behind this work is to make installing swift on linux seamless. this is something we hear about from the community time and again, and where the current tarball distribution falls short given swift's relatively large amount of system dependencies. to address this, we want to transition from tarballs to native installers where possible, with the following phases:

  1. develop native packages / installers for the distributions we support (centos, amazon linux, ubuntu) and others (fedora, debian, etc), using best practices for the given platform.
  2. offer the native packages / installers through swift.org, including signing them with the swift.org code signing certs. this means swift.org will need to expose a custom repository for that package type.
  3. deprecate tarballs distributions to any platform that has native packages / installers, and only create them for cases where there isn't a better packaging format.
  4. work with the official repositories for the various platforms to accept the specs, such that we can over time deprecate swift.org custom repository.

@futurejones
Copy link
Contributor

@tomerd thanks for this information.
It would be nice if we could have this included in the readme so that there is roadmap to follow and everybody knows what we are trying to achieve.
Also before everybody submits lots of pr's for all the different distributions and os's we need some sort of a design document outlining the basic requirements for all packages. This is needed to achieve uniformity across all the platforms.
The key items that need to be included are -

  • package name
  • versioning
  • iteration
  • maintainer
  • url
  • description
  • license
  • installation location

All these items should be the same across all the platforms and package systems.
None of these items have been discussed or agreed on at any level and we are already seeing fragmentation with package naming and install location.
The current use of swift-lang as the package name is an example. This name can not be used on the Ubuntu/Debian platforms as there is already a swift- family of packages. A hyphenated name shouldn't really be used as the main package name anyway.
swiftlang makes more sense as an official package name.
It would be great if we had somewhere to discuss, review and agree on all these items rather than using comments in a pr.

@tomerd
Copy link
Contributor Author

tomerd commented Oct 3, 2021

@futurejones totally agree, this is all very much wip and having such doc listing the goals and the open questions / issues would help drive this to completion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants