<% image = case platform when /x86_64-linux-gnu/ then "quay.io/pypa/manylinux2014_x86_64" when /x86-linux-gnu/ then "quay.io/pypa/manylinux2014_i686" else "ubuntu:20.04" end manylinux = !!(image =~ /manylinux/) %> FROM <%= image %> ## ## Install required base packages for compiling ruby ## <% if manylinux %> RUN yum install -y sudo ruby less git wget curl autoconf libtool cmake gcc-c++ xz readline-devel sqlite-devel openssl-devel libffi-devel libyaml-devel ## Prepare sudo RUN rm -f /usr/local/bin/sudo && \ groupadd -r sudo && \ echo "%sudo ALL=(ALL) ALL" >> /etc/sudoers <% else %> ENV DEBIAN_FRONTEND noninteractive RUN apt-get -y update && \ apt-get install -y sudo wget curl git-core build-essential xz-utils unzip dirmngr && \ apt-get install -y autoconf cmake pkg-config zlib1g-dev libreadline-dev libsqlite0-dev libssl-dev libyaml-dev libffi-dev && \ rm -rf /var/lib/apt/lists/* <% end %> ## ## install rbenv and ruby-build ## RUN groupadd -r rubyuser && useradd -r -g rubyuser -G sudo -p "" --create-home rubyuser ENV RBENV_ROOT=/usr/local/rbenv RBENV_RUBIES="2.5.9 3.1.3" # chown after running `rbenv init` because that command creates some subdirectories RUN git clone https://github.com/rbenv/rbenv.git ${RBENV_ROOT} && \ git clone https://github.com/rbenv/ruby-build.git ${RBENV_ROOT}/plugins/ruby-build && \ \ echo "export RBENV_ROOT=/usr/local/rbenv" >> /etc/rubybashrc && \ echo "export PATH=$RBENV_ROOT/bin:\$PATH" >> /etc/rubybashrc && \ $RBENV_ROOT/bin/rbenv init - --no-rehash bash >> /etc/rubybashrc && \ echo "source /etc/rubybashrc" >> /etc/bashrc && \ echo "source /etc/rubybashrc" >> /etc/bash.bashrc && \ \ chown -R rubyuser:rubyuser ${RBENV_ROOT} && \ find ${RBENV_ROOT} -type d -print0 | sudo xargs -0 chmod g+sw ENV BASH_ENV=/etc/rubybashrc ## ## Install cross compilers ## <% if platform =~ /x64-mingw-ucrt/ %> COPY --from=larskanis/mingw64-ucrt:20.04 \ /build/binutils-mingw-w64-x86-64_2.34-6ubuntu1.3+8.8_amd64.deb \ /build/g++-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_amd64.deb \ /build/gcc-mingw-w64-base_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_amd64.deb \ /build/gcc-mingw-w64-x86-64_9.3.0-17ubuntu1~20.04+22~exp1ubuntu4_amd64.deb \ /build/mingw-w64-common_7.0.0-2_all.deb \ /build/mingw-w64-x86-64-dev_7.0.0-2_all.deb \ /debs/ RUN dpkg -i /debs/*.deb <% elsif platform =~ /linux-musl/ %> COPY build/mk_musl_cross.sh /tmp RUN /tmp/mk_musl_cross.sh <%= target %> <% elsif !manylinux %> RUN apt-get -y update && \ apt-get install -y <% if platform =~ /darwin/ %> clang python lzma-dev libxml2-dev libssl-dev libc++-10-dev <% end %><% if platform =~ /aarch64-linux-gnu/ %> gcc-aarch64-linux-gnu g++-aarch64-linux-gnu <% end %><% if platform =~ /arm-linux-gnu/ %> gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf <% end %><% if platform =~ /x86-mingw32/ %> gcc-mingw-w64-i686 g++-mingw-w64-i686 <% end %><% if platform =~ /x64-mingw32/ %> gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 <% end %> && \ rm -rf /var/lib/apt/lists/* <% end %> <% if manylinux %> # Create dev tools x86-linux-* COPY build/mk_i686.rb /root/ RUN /root/mk_i686.rb <% end %> <% if platform =~ /darwin/ %> COPY build/mk_osxcross.sh /tmp RUN /tmp/mk_osxcross.sh <% end %> ## ## set up rake-compiler and install bootstrap rubies ## USER rubyuser # Install the bootstrap rubies RUN bash -c " \ echo 'gem: --no-ri --no-rdoc --no-document' >> ~/.gemrc && \ export CFLAGS='-s -O3 -fno-fast-math -fPIC' && \ for v in ${RBENV_RUBIES} ; do \ rbenv install \$v -- --disable-install-doc ; \ done && \ find ${RBENV_ROOT} -type d -print0 | sudo xargs -0 chmod g+w \ " # Install rake-compiler and patch it to build and install static libraries for Linux rubies COPY build/patches2 /home/rubyuser/patches RUN bash -c " \ for v in ${RBENV_RUBIES} ; do \ rbenv shell \$v && \ gem install rake-compiler -v1.2.5 && \ cd ${RBENV_ROOT}/versions/\$v/lib/ruby/gems/*/gems/rake-compiler-1.2.5 && \ patch -p1 < /home/rubyuser/patches/rake-compiler-1.2.5/*.patch ; \ done \ " # Install rake-compiler's cross rubies in global dir instead of /root RUN sudo mkdir -p /usr/local/rake-compiler && \ sudo chown rubyuser.rubyuser /usr/local/rake-compiler && \ ln -s /usr/local/rake-compiler ~/.rake-compiler <% # # Build ruby versions prior to ruby2_keywords using ruby-2.5 # Build ruby versions with ruby2_keywords using ruby-3.x # # Note that parallel builds of ruby with make flag `-j` are often flaky, see # https://bugs.ruby-lang.org/issues/18506 # xrubies_build_plan = if platform =~ /x64-mingw-ucrt/ [ # Rubyinstaller-3.1.0+ is platform x64-mingw-ucrt ["3.3.0-rc1:3.2.0:3.1.0", "3.1.3"], ] elsif platform =~ /x64-mingw32/ [ # Rubyinstaller prior to 3.1.0 is platform x64-mingw32 ["2.6.0:2.5.0:2.4.0", "2.5.9"], ["3.0.0:2.7.0", "3.1.3"], ] else [ ["2.6.0:2.5.0:2.4.0", "2.5.9"], ["3.3.0-rc1:3.2.0:3.1.0:3.0.0:2.7.0", "3.1.3"], ] end strip = '-s' if platform !~ /darwin/ xrubies_build_plan.each do |xrubies, bootstrap_ruby_version| %> RUN bash -c " \ rbenv shell <%= bootstrap_ruby_version %> && \ export CPPFLAGS='<%= "-D__USE_MINGW_ANSI_STDIO=1" if platform =~ /x64-mingw-ucrt/ %>' && \ export CFLAGS='-O1 -fno-omit-frame-pointer -fno-fast-math -fstack-protector-strong <%= strip %>' && \ export LDFLAGS='-pipe <%= strip %>' && \ <%= "export LIBS='-l:libssp.a' &&" if platform =~ /mingw/ %> \ <%= "export CC=#{target}-clang &&" if platform =~ /darwin/ %> \ export MAKE='make V=1' && \ rake-compiler cross-ruby VERSION=<%= xrubies %> HOST=<%= target %> && \ rm -rf ~/.rake-compiler/builds ~/.rake-compiler/sources \ " <% end %> # " <% if platform =~ /linux/ %> # Avoid linking against libruby shared object. # See also https://github.com/rake-compiler/rake-compiler-dock/issues/13 RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby.so | xargs rm RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby-static.a | while read f ; do cp $f `echo $f | sed s/-static//` ; done RUN find /usr/local/rake-compiler/ruby/*linux*/ -name libruby.a | while read f ; do ar t $f | xargs ar d $f ; done RUN find /usr/local/rake-compiler/ruby/*linux*/ -name mkmf.rb | while read f ; do sed -i ':a;N;$!ba;s/TRY_LINK = [^\n]*\n[^\n]*\n[^\n]*LOCAL_LIBS)/& -lruby-static -lpthread -lrt -ldl <% if platform =~ /x86/ %> -lcrypt <% end %>/' $f ; done <% end %> <% if platform =~ /mingw/ %> # RubyInstaller doesn't install libgcc -> link it static. RUN find /usr/local/rake-compiler/ruby/*mingw*/ -name rbconfig.rb | while read f ; do sed -i 's/."LDFLAGS". = "/&-static-libgcc /' $f ; done # Raise Windows-API to Vista (affects ruby < 2.6 only) RUN find /usr/local/rake-compiler/ruby -name rbconfig.rb | while read f ; do sed -i 's/0x0501/0x0600/' $f ; done # Don't link to static libruby RUN find /usr/local/rake-compiler/ruby -name lib*-ruby*.dll.a | while read f ; do n=`echo $f | sed s/.dll//` ; mv $f $n ; done <% end %> # ruby-2.5 links to libcrypt, which isn't necessary for extensions RUN find /usr/local/rake-compiler/ruby -name rbconfig.rb | while read f ; do sed -i 's/-lcrypt//' $f ; done <% if platform =~ /darwin/ %> # ruby-3.2+ on darwin links with `-bundle_loader`, # - see https://github.com/rake-compiler/rake-compiler-dock/issues/87 # - note that we do this for "3.[2-9].0" to match rubies 3.2 and later # - and we add a "*" on the end for "3.[2-9].0*" to match prereleases like "3.3.0+0" RUN find /usr/local/rake-compiler/ruby/*/*/lib/ruby/3.[2-9].0* -name rbconfig.rb | \ while read f ; do sed -i 's/\["EXTDLDFLAGS"\] = "/&-Wl,-flat_namespace /' $f ; done <% end %> ## ## Final adjustments ## USER root <% if platform =~ /mingw/ %> # Install wrappers for strip commands as a workaround for "Protocol error" in boot2docker. COPY build/strip_wrapper_vbox /root/ RUN mv /usr/bin/<%= target %>-strip /usr/bin/<%= target %>-strip.bin && \ ln /root/strip_wrapper_vbox /usr/bin/<%= target %>-strip # Use posix pthread for mingw so that C++ standard library for thread could be # available such as std::thread, std::mutex, so on. # https://sourceware.org/pthreads-win32/ RUN printf "1\n" | update-alternatives --config <%= target %>-gcc && \ printf "1\n" | update-alternatives --config <%= target %>-g++ <% end %> <% if platform =~ /darwin/ %> # Install wrapper around strip to re-sign binaries (ad-hoc signature) COPY build/strip_wrapper_codesign /root/ RUN mv /opt/osxcross/target/bin/<%= target %>-strip /opt/osxcross/target/bin/<%= target %>-strip.bin && \ ln /root/strip_wrapper_codesign /opt/osxcross/target/bin/<%= target %>-strip <% end %> <% if manylinux %> # Enable modern compiler toolset of manylinux image RUN echo "export PATH=\$DEVTOOLSET_ROOTPATH/usr/bin:\$PATH" >> /etc/rubybashrc # Add prefixed versions of compiler tools RUN for f in addr2line gcc gcov-tool ranlib ar dwp gcc-ranlib nm readelf as elfedit gcc-ar gprof objcopy size c++filt g++ gcov ld objdump strings cpp gcc-nm pkg-config strip ; do ln -sf $DEVTOOLSET_ROOTPATH/usr/bin/$f $DEVTOOLSET_ROOTPATH/usr/bin/<%= target %>-$f ; done # Use builtin functions of newer gcc to avoid linker issues on Musl based Linux # TODO: remove in v1.6.0 once musl builds have been out for full minor release cycle, see 864be5b2 COPY build/math_h.patch /root/ RUN cd /usr/include/ && \ patch -p1 < /root/math_h.patch <% end %> <% if platform =~ /arm64-darwin/ %> # Add a arm64 darwin target as alternative to aarch64 RUN grep -E 'rbconfig-aarch64-darwin' /usr/local/rake-compiler/config.yml | sed 's/rbconfig-[a-z0-9_]*-darwin/rbconfig-<%= platform %>/' >> /usr/local/rake-compiler/config.yml <% end %> # Install SIGINT forwarder COPY build/sigfw.c /root/ RUN gcc $HOME/sigfw.c -o /usr/bin/sigfw # Install user mapper COPY build/runas /usr/bin/ COPY build/rcd-env.sh /etc/profile.d/ RUN echo 'source /etc/profile.d/rcd-env.sh' >> /etc/rubybashrc # Install sudoers configuration COPY build/sudoers /etc/sudoers.d/rake-compiler-dock RUN bash -c "rbenv global 3.1.3" ENV RUBY_CC_VERSION 3.3.0:3.2.0:3.1.0:3.0.0:2.7.0:2.6.0:2.5.0:2.4.0 CMD bash