1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
# Copyright (C) the Rugged contributors. All rights reserved.
#
# This file is part of Rugged, distributed under the MIT license.
# For full terms see the included LICENSE file.
require 'mkmf'
require 'timeout'
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
$CFLAGS << " #{ENV["CFLAGS"]}"
$CFLAGS << " -g"
$CFLAGS << " -O3" unless $CFLAGS[/-O\d/]
$CFLAGS << " -Wall -Wno-comment"
cmake_flags = [ ENV["CMAKE_FLAGS"] ]
cmake_flags << "-DBUILD_CLI=OFF"
cmake_flags << "-DBUILD_TESTS=OFF"
cmake_flags << "-DREGEX_BACKEND=builtin"
cmake_flags << "-DUSE_SHA1DC=ON" if with_config("sha1dc")
cmake_flags << "-DUSE_SSH=ON" if with_config("ssh")
def sys(cmd)
puts " -- #{cmd}"
unless ret = xsystem(cmd)
raise "ERROR: '#{cmd}' failed"
end
ret
end
# Thrown when we detect CMake is taking too long and we killed it
class CMakeTimeout < StandardError
end
def self.run_cmake(timeout, args)
# Set to process group so we can kill it and its children
pgroup = Gem.win_platform? ? :new_pgroup : :pgroup
pid = Process.spawn("cmake #{args}", pgroup => true)
Timeout.timeout(timeout) do
Process.waitpid(pid)
end
rescue Timeout::Error
# Kill it, #detach is essentially a background wait, since we don't actually
# care about waiting for it now
Process.kill(-9, pid)
Process.detach(pid)
raise CMakeTimeout.new("cmake has exceeded its timeout of #{timeout}s")
end
MAKE = if Gem.win_platform?
# On Windows, Ruby-DevKit only has 'make'.
find_executable('make')
else
find_executable('gmake') || find_executable('make')
end
if !MAKE
abort "ERROR: GNU make is required to build Rugged."
end
CWD = File.expand_path(File.dirname(__FILE__))
if arg_config("--use-system-libraries", !!ENV['RUGGED_USE_SYSTEM_LIBRARIES'])
puts "Building Rugged using system libraries.\n"
dir_config('git2').any? or pkg_config('libgit2')
else
if !find_executable('cmake')
abort "ERROR: CMake is required to build Rugged."
end
if !Gem.win_platform? && !find_executable('pkg-config')
abort "ERROR: pkg-config is required to build Rugged."
end
Dir.chdir(LIBGIT2_DIR) do
Dir.mkdir("build") if !Dir.exist?("build")
Dir.chdir("build") do
# On Windows, Ruby-DevKit is MSYS-based, so ensure to use MSYS Makefiles.
generator = "-G \"MSYS Makefiles\"" if Gem.win_platform?
run_cmake(5 * 60, ".. -DBUILD_TESTS=OFF -DUSE_THREADS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS=-fPIC -DCMAKE_BUILD_TYPE=RelWithDebInfo #{cmake_flags.join(' ')} #{generator}")
sys(MAKE)
# "normal" libraries (and libgit2 builds) get all these when they build but we're doing it
# statically so we put the libraries in by hand. It's important that we put the libraries themselves
# in $LIBS or the final linking stage won't pick them up
if Gem.win_platform?
$LDFLAGS << " " + "-L#{Dir.pwd}/deps/winhttp"
$LIBS << " -lwinhttp -lcrypt32 -lrpcrt4 -lole32 -lz -lssh2"
else
pcfile = File.join(LIBGIT2_DIR, "build", "libgit2.pc")
$LDFLAGS << " " + `pkg-config --libs --static #{pcfile}`.strip
end
end
end
# Prepend the vendored libgit2 build dir to the $DEFLIBPATH.
#
# By default, $DEFLIBPATH includes $(libpath), which usually points
# to something like /usr/lib for system ruby versions (not those
# installed through rbenv or rvm).
#
# This was causing system-wide libgit2 installations to be preferred
# over of our vendored libgit2 version when building rugged.
#
# By putting the path to the vendored libgit2 library at the front of
# $DEFLIBPATH, we can ensure that our bundled version is always used.
$DEFLIBPATH.unshift("#{LIBGIT2_DIR}/build")
dir_config('git2', "#{LIBGIT2_DIR}/include", "#{LIBGIT2_DIR}/build")
end
unless have_library 'git2' and have_header 'git2.h'
abort "ERROR: Failed to build libgit2"
end
create_makefile("rugged/rugged")
|