Check that ffi-compiler loads before using it to define tasks. (#14538)
Fixes #14509
Closes #14538
COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14538 from JasonLunn:fix_14509 a3f9d0bd4f1f8036253c7a794a61e8cc84b4483c
PiperOrigin-RevId: 577837541
diff --git a/ruby/lib/google/tasks/ffi.rake b/ruby/lib/google/tasks/ffi.rake
index 00e665f..c7b2a8e 100644
--- a/ruby/lib/google/tasks/ffi.rake
+++ b/ruby/lib/google/tasks/ffi.rake
@@ -1,5 +1,3 @@
-require "ffi-compiler/compile_task"
-
# # @param task [FFI::Compiler::CompileTask] task to configure
def configure_common_compile_task(task)
if FileUtils.pwd.include? 'ext'
@@ -49,46 +47,56 @@
end
end
-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"
+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
- 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 << "/range2-neon.c"
- c.exclude << "/range2-sse.c"
- c.exclude << "/naive.c"
- c.exclude << "/ruby-upb.c"
- 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 << "/range2-neon.c"
+ c.exclude << "/range2-sse.c"
+ c.exclude << "/naive.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
+ # 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
-