File: ffi.rake

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (100 lines) | stat: -rw-r--r-- 3,725 bytes parent folder | download | duplicates (6)
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
# # @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