Skip to content

Commit

Permalink
Allowing for creation of pre-compiled gems, using rack-compiler-dock.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasnoble committed Jan 28, 2016
1 parent b8e2f9c commit cb287a1
Show file tree
Hide file tree
Showing 17 changed files with 312 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ out
.ycm_extra_conf.py

# XCode
build/
^build/
*.pbxuser
!default.pbxuser
*.mode1v3
Expand Down
23 changes: 22 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ RuboCop::RakeTask.new(:rubocop) do |task|
task.patterns = ['src/ruby/{lib,spec}/**/*.rb']
end

spec = Gem::Specification.load('grpc.gemspec')

Gem::PackageTask.new(spec) do |pkg|
end

# Add the extension compiler task
Rake::ExtensionTask.new 'grpc' do |ext|
Rake::ExtensionTask.new('grpc', spec) do |ext|
ext.source_pattern = '**/*.{c,h}'
ext.ext_dir = File.join('src', 'ruby', 'ext', 'grpc')
ext.lib_dir = File.join('src', 'ruby', 'lib', 'grpc')
ext.cross_compile = true
ext.cross_platform = ['x86-mingw32', 'x64-mingw32']
end

# Define the test suites
Expand Down Expand Up @@ -51,6 +58,20 @@ namespace :suite do
end
end

desc 'Build the gem file under rake_compiler_dock'
task 'gem:windows' do
require 'digest'
require 'rake_compiler_dock'
version = Digest::SHA1.file('third_party/rake-compiler-dock/Dockerfile').hexdigest
image_name = 'grpc/rake-compiler-dock:' + version
cmd = "docker build -t #{image_name} third_party/rake-compiler-dock"
puts cmd
system cmd
exit 1 unless $? == 0
ENV['RAKE_COMPILER_DOCK_IMAGE'] = image_name
RakeCompilerDock.sh "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.6:2.0.0"
end

# Define dependencies between the suites.
task 'suite:wrapper' => [:compile, :rubocop]
task 'suite:idiomatic' => 'suite:wrapper'
Expand Down
21 changes: 11 additions & 10 deletions grpc.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 2.0.0'
s.requirements << 'libgrpc ~> 0.11.0 needs to be installed'

s.files = %w( Rakefile Makefile )
s.files = %w( Makefile )
s.files += %w( etc/roots.pem )
s.files += Dir.glob('src/ruby/bin/**/*')
s.files += Dir.glob('src/ruby/ext/**/*')
Expand All @@ -33,16 +33,17 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY

s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_dependency 'googleauth', '~> 0.5.1'

s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'logging', '~> 2.0'
s.add_development_dependency 'simplecov', '~> 0.9'
s.add_development_dependency 'rake', '~> 10.4'
s.add_development_dependency 'rake-compiler', '~> 0.9'
s.add_development_dependency 'rspec', '~> 3.2'
s.add_development_dependency 'rubocop', '~> 0.30.0'
s.add_development_dependency 'signet', '~>0.7.0'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'logging', '~> 2.0'
s.add_development_dependency 'simplecov', '~> 0.9'
s.add_development_dependency 'rake', '~> 10.4'
s.add_development_dependency 'rake-compiler', '~> 0.9'
s.add_development_dependency 'rake-compiler-dock', '~> 0.5'
s.add_development_dependency 'rspec', '~> 3.2'
s.add_development_dependency 'rubocop', '~> 0.30.0'
s.add_development_dependency 'signet', '~> 0.7.0'

s.extensions = %w(src/ruby/ext/grpc/extconf.rb)

Expand Down
7 changes: 6 additions & 1 deletion src/ruby/lib/grpc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@
ENV['GRPC_DEFAULT_SSL_ROOTS_FILE_PATH'] = ssl_roots_path
end

begin
require "grpc/#{RUBY_VERSION.sub(/\.\d$/, '')}/grpc"
rescue LoadError
require 'grpc/grpc'
end

require 'grpc/errors'
require 'grpc/grpc'
require 'grpc/logconfig'
require 'grpc/notifier'
require 'grpc/version'
Expand Down
21 changes: 11 additions & 10 deletions templates/grpc.gemspec.template
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
s.required_ruby_version = '>= 2.0.0'
s.requirements << 'libgrpc ~> 0.11.0 needs to be installed'

s.files = %w( Rakefile Makefile )
s.files = %w( Makefile )
s.files += %w( etc/roots.pem )
s.files += Dir.glob('src/ruby/bin/**/*')
s.files += Dir.glob('src/ruby/ext/**/*')
Expand All @@ -35,16 +35,17 @@
s.platform = Gem::Platform::RUBY

s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_dependency 'googleauth', '~> 0.5.1'

s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'logging', '~> 2.0'
s.add_development_dependency 'simplecov', '~> 0.9'
s.add_development_dependency 'rake', '~> 10.4'
s.add_development_dependency 'rake-compiler', '~> 0.9'
s.add_development_dependency 'rspec', '~> 3.2'
s.add_development_dependency 'rubocop', '~> 0.30.0'
s.add_development_dependency 'signet', '~>0.7.0'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'logging', '~> 2.0'
s.add_development_dependency 'simplecov', '~> 0.9'
s.add_development_dependency 'rake', '~> 10.4'
s.add_development_dependency 'rake-compiler', '~> 0.9'
s.add_development_dependency 'rake-compiler-dock', '~> 0.5'
s.add_development_dependency 'rspec', '~> 3.2'
s.add_development_dependency 'rubocop', '~> 0.30.0'
s.add_development_dependency 'signet', '~> 0.7.0'

s.extensions = %w(src/ruby/ext/grpc/extconf.rb)

Expand Down
109 changes: 109 additions & 0 deletions third_party/rake-compiler-dock/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
FROM ubuntu:14.04

RUN apt-get -y update && \
apt-get install -y curl git-core mingw-w64 xz-utils build-essential wget unzip

RUN mkdir -p /opt/mingw && \
curl -SL http://downloads.sourceforge.net/mingw-w64/i686-w64-mingw32-gcc-4.7.2-release-linux64_rubenvb.tar.xz | \
tar -xJC /opt/mingw && \
echo "export PATH=\$PATH:/opt/mingw/mingw32/bin" >> /etc/rubybashrc

RUN mkdir -p /opt/mingw && \
curl -SL http://downloads.sourceforge.net/mingw-w64/x86_64-w64-mingw32-gcc-4.7.2-release-linux64_rubenvb.tar.xz | \
tar -xJC /opt/mingw && \
echo "export PATH=\$PATH:/opt/mingw/mingw64/bin" >> /etc/rubybashrc

# Add "rvm" as system group, to avoid conflicts with host GIDs typically starting with 1000
RUN groupadd -r rvm && useradd -r -g rvm -G sudo -p "" --create-home rvm && \
echo "source /etc/profile.d/rvm.sh" >> /etc/rubybashrc
USER rvm

# install rvm, RVM 1.26.0+ has signed releases, source rvm for usage outside of package scripts
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3 && \
(curl -L http://get.rvm.io | sudo bash -s stable) && \
bash -c " \
source /etc/rubybashrc && \
rvmsudo rvm cleanup all "

# Import patch files for ruby and gems
COPY build/patches /home/rvm/patches/
ENV BASH_ENV /etc/rubybashrc

# install rubies and fix permissions on
RUN bash -c " \
export CFLAGS='-s -O3 -fno-fast-math -fPIC' && \
for v in 2.3.0 ; do \
rvm install \$v --patch \$(echo ~/patches/ruby-\$v/* | tr ' ' ','); \
done && \
rvm cleanup all && \
find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "

# Install rake-compiler and typical gems in all Rubies
# do not generate documentation for gems
RUN echo "gem: --no-ri --no-rdoc" >> ~/.gemrc && \
bash -c " \
rvm all do gem install bundler rake-compiler hoe mini_portile rubygems-tasks json && \
rvm 2.3.0 do gem install mini_portile2 && \
find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "

# Install rake-compiler's cross rubies in global dir instead of /root
RUN sudo mkdir -p /usr/local/rake-compiler && \
sudo chown rvm.rvm /usr/local/rake-compiler && \
ln -s /usr/local/rake-compiler ~/.rake-compiler

# Patch rake-compiler to avoid build of ruby extensions
RUN cd /usr/local/rvm/gems/ruby-2.3.0/gems/rake-compiler-0.9.5 && patch -p1 < /home/rvm/patches/rake-compiler-0.9.5/without-exts.diff ; \
true

RUN bash -c "rvm use 2.3.0 --default && \
export MAKE=\"make -j`nproc`\" CFLAGS='-s -O1 -fno-omit-frame-pointer -fno-fast-math' && \
rake-compiler cross-ruby VERSION=2.3.0 HOST=i686-w64-mingw32 && \
rake-compiler cross-ruby VERSION=2.3.0 HOST=x86_64-w64-mingw32 && \
rake-compiler cross-ruby VERSION=2.2.2 HOST=i686-w64-mingw32 && \
rake-compiler cross-ruby VERSION=2.2.2 HOST=x86_64-w64-mingw32 && \
rake-compiler cross-ruby VERSION=2.1.6 HOST=i686-w64-mingw32 && \
rake-compiler cross-ruby VERSION=2.1.6 HOST=x86_64-w64-mingw32 && \
rake-compiler cross-ruby VERSION=2.0.0-p645 HOST=i686-w64-mingw32 && \
rake-compiler cross-ruby VERSION=2.0.0-p645 HOST=x86_64-w64-mingw32 && \
rm -rf ~/.rake-compiler/builds ~/.rake-compiler/sources && \
find /usr/local/rvm -type d -print0 | sudo xargs -0 chmod g+sw "

RUN bash -c " \
rvm alias create 2.3 2.3.0 "

USER root

# Fix paths in rake-compiler/config.yml and add rvm and mingw-tools to the global bashrc
RUN sed -i -- "s:/root/.rake-compiler:/usr/local/rake-compiler:g" /usr/local/rake-compiler/config.yml && \
echo "source /etc/profile.d/rvm.sh" >> /etc/bash.bashrc && \
echo "export PATH=\$PATH:/opt/mingw/mingw32/bin" >> /etc/bash.bashrc && \
echo "export PATH=\$PATH:/opt/mingw/mingw64/bin" >> /etc/bash.bashrc

# Install wrappers for strip commands as a workaround for "Protocol error" in boot2docker.
COPY build/strip_wrapper /root/
RUN mv /opt/mingw/mingw32/bin/i686-w64-mingw32-strip /opt/mingw/mingw32/bin/i686-w64-mingw32-strip.bin && \
mv /opt/mingw/mingw64/bin/x86_64-w64-mingw32-strip /opt/mingw/mingw64/bin/x86_64-w64-mingw32-strip.bin && \
mv /usr/bin/i686-w64-mingw32-strip /usr/bin/i686-w64-mingw32-strip.bin && \
mv /usr/bin/x86_64-w64-mingw32-strip /usr/bin/x86_64-w64-mingw32-strip.bin && \
ln /root/strip_wrapper /opt/mingw/mingw32/bin/i686-w64-mingw32-strip && \
ln /root/strip_wrapper /opt/mingw/mingw64/bin/x86_64-w64-mingw32-strip && \
ln /root/strip_wrapper /usr/bin/i686-w64-mingw32-strip && \
ln /root/strip_wrapper /usr/bin/x86_64-w64-mingw32-strip

RUN find / -name rbconfig.rb | while read f ; do sed -i 's/0x0501/0x0600/' $f ; done
RUN find / -name win32.h | while read f ; do sed -i 's/gettimeofday/rb_gettimeofday/' $f ; done
RUN sed -i 's/defined.__MINGW64__.$/1/' /usr/local/rake-compiler/ruby/i686-w64-mingw32/ruby-2.0.0-p645/include/ruby-2.0.0/ruby/win32.h

# Install SIGINT forwarder
COPY build/sigfw.c /root/
RUN gcc $HOME/sigfw.c -o /usr/local/bin/sigfw

# Install user mapper
COPY build/runas /usr/local/bin/

# Install sudoers configuration
COPY build/sudoers /etc/sudoers.d/rake-compiler-dock

ENV RUBY_CC_VERSION 2.3.0:2.2.2:2.1.6:2.0.0

CMD bash
22 changes: 22 additions & 0 deletions third_party/rake-compiler-dock/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Copyright (c) 2015 Lars Kanis

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 change: 1 addition & 0 deletions third_party/rake-compiler-dock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a modified Dockerfile taken from [rake-compiler-dock](https://github.com/rake-compiler/rake-compiler-dock) for the purpose of building gRPC's ruby gem.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
diff --git a/tasks/bin/cross-ruby.rake b/tasks/bin/cross-ruby.rake
index 6acc816..6aa2a49 100644
--- a/tasks/bin/cross-ruby.rake
+++ b/tasks/bin/cross-ruby.rake
@@ -135,8 +135,7 @@ file "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/Makefile" => ["#{USER
"--build=#{RUBY_BUILD}",
'--enable-shared',
'--disable-install-doc',
- '--without-tk',
- '--without-tcl'
+ '--with-ext='
]

# Force Winsock2 for Ruby 1.8, 1.9 defaults to it
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
diff --git a/configure b/configure
index 55157af..6630eba 100755
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/configure b/configure
index 898730c..cfe6253 100755
--- a/configure
+++ b/configure
@@ -14695,7 +14695,7 @@ for ac_func in fmod killpg wait4 waitpid fork spawnv syscall __syscall chroot ge
setsid telldir seekdir fchmod cosh sinh tanh log2 round\
setuid setgid daemon select_large_fdset setenv unsetenv\
mktime timegm gmtime_r clock_gettime gettimeofday poll ppoll\
- pread sendfile shutdown sigaltstack dl_iterate_phdr
+ pread shutdown sigaltstack dl_iterate_phdr
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
diff --git a/configure b/configure
index 55157af..6630eba 100755
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/configure b/configure
index ebe3d8c..a336b73 100755
--- a/configure
+++ b/configure
@@ -18943,7 +18943,6 @@ do :
ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile"
if test "x$ac_cv_func_sendfile" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define HAVE_SENDFILE 1
_ACEOF

fi
12 changes: 12 additions & 0 deletions third_party/rake-compiler-dock/build/runas
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

groupadd -g "$GID" "$GROUP"
mkdir -p /tmp/home
useradd -g "$GID" -u "$UID" -G rvm,sudo -p "" -b /tmp/home -m "$USER"

HOME=$(bash <<< "echo ~$USER")
ln -s /usr/local/rake-compiler "$HOME"/.rake-compiler

sudo -u "$USER" --set-home \
BASH_ENV=/etc/rubybashrc \
-- "$@"
43 changes: 43 additions & 0 deletions third_party/rake-compiler-dock/build/sigfw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* This program handles SIGINT and forwards it to another process.
* It is intended to be run as PID 1.
*
* Docker starts processes with "docker run" as PID 1.
* On Linux, the default signal handler for PID 1 ignores any signals.
* Therefore Ctrl-C aka SIGINT is ignored per default.
*/

#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

int pid = 0;

void
handle_sigint (int signum)
{
if(pid)
kill(pid, SIGINT);
}

int main(int argc, char *argv[]){
struct sigaction new_action;
int status = -1;

/* Set up the structure to specify the new action. */
new_action.sa_handler = handle_sigint;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;

sigaction (SIGINT, &new_action, (void*)0);

pid = fork();
if(pid){
wait(&status);
return WEXITSTATUS(status);
}else{
status = execvp(argv[1], &argv[1]);
perror("exec");
return status;
}
}
Loading

0 comments on commit cb287a1

Please sign in to comment.