This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
# # @param task [FFI::Compiler::CompileTask] task to configure
|
||||
def configure_common_compile_task(task)
|
||||
if FileUtils.pwd.include? 'ext'
|
||||
src_dir = '.'
|
||||
third_party_path = 'third_party/utf8_range'
|
||||
else
|
||||
src_dir = 'ext/google/protobuf_c'
|
||||
third_party_path = 'ext/google/protobuf_c/third_party/utf8_range'
|
||||
end
|
||||
|
||||
task.add_include_path third_party_path
|
||||
task.add_define 'NDEBUG'
|
||||
task.cflags << "-std=gnu99 -O3"
|
||||
[
|
||||
:convert, :defs, :map, :message, :protobuf, :repeated_field, :wrap_memcpy
|
||||
].each { |file| task.exclude << "/#{file}.c" }
|
||||
task.ext_dir = src_dir
|
||||
task.source_dirs = [src_dir]
|
||||
if RbConfig::CONFIG['target_os'] =~ /darwin|linux/
|
||||
task.cflags << "-Wall -Wsign-compare -Wno-declaration-after-statement"
|
||||
end
|
||||
end
|
||||
|
||||
# FFI::CompilerTask's constructor walks the filesystem at task definition time
|
||||
# to create subtasks for each source file, so files from third_party must be
|
||||
# copied into place before the task is defined for it to work correctly.
|
||||
# TODO Is there a sane way to check for generated protos under lib too?
|
||||
def with_generated_files
|
||||
expected_path = FileUtils.pwd.include?('ext') ? 'third_party/utf8_range' : 'ext/google/protobuf_c/third_party/utf8_range'
|
||||
if File.directory?(expected_path)
|
||||
yield
|
||||
else
|
||||
task :default do
|
||||
# It is possible, especially in cases like the first invocation of
|
||||
# `rake test` following `rake clean` or a fresh checkout that the
|
||||
# `copy_third_party` task has been executed since initial task definition.
|
||||
# If so, run the task definition block now and invoke it explicitly.
|
||||
if File.directory?(expected_path)
|
||||
yield
|
||||
Rake::Task[:default].invoke
|
||||
else
|
||||
raise "Missing directory #{File.absolute_path(expected_path)}." +
|
||||
" Did you forget to run `rake copy_third_party` before building" +
|
||||
" native extensions?"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
require "ffi-compiler/compile_task"
|
||||
|
||||
desc "Compile Protobuf library for FFI"
|
||||
namespace "ffi-protobuf" do
|
||||
with_generated_files do
|
||||
# Compile Ruby UPB separately in order to limit use of -DUPB_BUILD_API to one
|
||||
# compilation unit.
|
||||
desc "Compile UPB library for FFI"
|
||||
namespace "ffi-upb" do
|
||||
with_generated_files do
|
||||
FFI::Compiler::CompileTask.new('ruby-upb') do |c|
|
||||
configure_common_compile_task c
|
||||
c.add_define "UPB_BUILD_API"
|
||||
c.exclude << "/glue.c"
|
||||
c.exclude << "/shared_message.c"
|
||||
c.exclude << "/shared_convert.c"
|
||||
if RbConfig::CONFIG['target_os'] =~ /darwin|linux/
|
||||
c.cflags << "-fvisibility=hidden"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
FFI::Compiler::CompileTask.new 'protobuf_c_ffi' do |c|
|
||||
configure_common_compile_task c
|
||||
# Ruby UPB was already compiled with different flags.
|
||||
c.exclude << "/utf8_range.c"
|
||||
c.exclude << "/ruby-upb.c"
|
||||
end
|
||||
|
||||
# Setup dependencies so that the .o files generated by building ffi-upb are
|
||||
# available to link here.
|
||||
# TODO Can this be simplified? Can the single shared library be used
|
||||
# instead of the object files?
|
||||
protobuf_c_task = Rake::Task[:default]
|
||||
protobuf_c_shared_lib_task = Rake::Task[protobuf_c_task.prereqs.last]
|
||||
ruby_upb_shared_lib_task = Rake::Task[:"ffi-upb:default"].prereqs.first
|
||||
Rake::Task[ruby_upb_shared_lib_task].prereqs.each do |dependency|
|
||||
protobuf_c_shared_lib_task.prereqs.prepend dependency
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
desc "Compile Protobuf library for FFI"
|
||||
namespace "ffi-protobuf" do
|
||||
task :default do
|
||||
warn "Skipping build of FFI; `gem install ffi-compiler` to enable."
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user