morandi 0.12.0 → 0.99.03

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d1a30842ccacd85b3680f80c8d4a68c52dd96edcf5136963a73c9049089ab5b
4
- data.tar.gz: 9b2ee86c53d336481c377834baef371d16bba4886a0272c61211077ab8cb8da6
3
+ metadata.gz: a794ac03476df828589c8239af24558daba1b32c4db9052f1dcf3704442eae43
4
+ data.tar.gz: 71fb0af31081d29907392d57ceb7adda9fc6b277835fd7540a9c91a6b1b9c90c
5
5
  SHA512:
6
- metadata.gz: cdb7f1ff080d549101e49c030c76dda02f433e9d4e7824e1abb6ebdf149268c0e406334bac8ea6848a7008293ceb8fd43f43d605623b771989fddc6df4faccd5
7
- data.tar.gz: c7a00a804bb12717fba9c3e613ba813d1213d64934b8c2e3a21b9d1b10367d13f9b33f8fe0677b6b9e626d0bbf65806071286e7c6e3b6a57db6d4cfef68c4295
6
+ metadata.gz: be85f2a459dad73012fe696f285f1eae17b098e48002f5da9cf868ed876854b915115e1e6f85929948427208d2b3363abe3d7b492b6187e729bf408ad6fccb95
7
+ data.tar.gz: 78beadc94f1387ff9af6d9c00d2f518f17d71f241880a5d2a828568dfaa2eb1b2aade57b198fc7f8ceeae429c1445d1c9c36c9fd461c84b3516e88964c32bf19
data/CHANGELOG.md CHANGED
@@ -4,7 +4,30 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## Last updated 10.12.2020
7
+ ## Unreleased
8
+ ### Added
9
+ - Copied pixbufutils and redeye gems into main gem
10
+ - Added gdk_pixbuf_cairo C extension to convert between GdkPixbufs and ImageSurfaces
11
+ - Added Ruby 3 support
12
+ - Bumped version to 0.99.01 in preparation for a 1.0 release
13
+
14
+ ### Removed
15
+ - support for Ruby 2.0 (and illusion of it being tested by CI)
16
+ - support for Ruby 2.3
17
+ - gtk2 dependency
18
+
19
+ ## [0.13.0] 16.12.2020
20
+ ### Fixed
21
+ - Refactored test suite
22
+ - Fixed most rubocop offenses
23
+ ### Aded
24
+ - CI pipeline
25
+ - rubocop
26
+ - Development image
27
+
28
+ ## [0.12.1] 10.12.2020
29
+ ### Fixed
30
+ - Removed large test image
8
31
 
9
32
  ## [0.12.0] 10.12.2020
10
33
  ### Fixed
data/README.md CHANGED
@@ -5,7 +5,7 @@ morandi-js.
5
5
 
6
6
  ## Installation
7
7
 
8
- Install `liblcms2-utils` to provide the `jpgicc` command used by `Morandi::ProfiledPixbuf`
8
+ Install `liblcms2-utils` to provide the `jpgicc` command used by `Morandi::ProfiledPixbuf`. Also ensure that your host system has `imagemagick` installed, which is required bi the `colorscore` gem.
9
9
 
10
10
  Add this line to your application's Gemfile:
11
11
 
@@ -36,6 +36,7 @@ contrast | Integer -20..20 | Change image contrast
36
36
  sharpen | Integer -5..5 | Sharpen / Blur (negative value)
37
37
  redeye | Array[[Integer,Integer],...] | Apply redeye correction at point
38
38
  angle | Integer 0,90,180,270 | Rotate image
39
+ straighten | Float | Rotate by N degrees and zoom
39
40
  crop | Array[Integer,Integer,Integer,Integer] | Crop image
40
41
  fx | String greyscale,sepia,bluetone | Apply colour filters
41
42
  border-style | String square,retro | Set border style
@@ -49,3 +50,7 @@ quality | String '1'..'100' | Set JPG compression value, defaults to 97%
49
50
  3. Commit your changes (`git commit -am 'Add some feature'`)
50
51
  4. Push to the branch (`git push origin my-new-feature`)
51
52
  5. Create new Pull Request
53
+
54
+ ### Development
55
+
56
+ Since this gem depends on the `liblcms2-utils` library, which can be awkward to install on some operating systems, we also provide a development docker image. A Makefile is also provided as a simple CLI. To build the image and run the container, type `make` from the project root. The container itself runs `guard` as its main process. Running the container via `make` will drop you into the guard prompt, which will run the test suite whenever any of the source code or tests are changed. The tests can be kicked-off manually via the `all` command at the guard prompt. Individual test can be run using the `focus: true` annotation on an example or describe block. If you need to access a bash shell in the container (for example, to run rubocop), use the command `make shell`.
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/GlobalVars
4
+ require 'mkmf'
5
+
6
+ require 'English'
7
+ require 'rubygems'
8
+ gem 'glib2'
9
+ require 'mkmf-gnome'
10
+
11
+ def macos?
12
+ !!(RUBY_PLATFORM =~ /darwin/)
13
+ end
14
+
15
+ def clang?
16
+ cc_version = `#{RbConfig.expand('$(CC) --version'.dup)}`
17
+ cc_version.match?(/clang/i)
18
+ end
19
+
20
+ # XCode 14 warns if `-Wl,-undefined dynamic_lookup` is specified, and as
21
+ # a result Ruby interpreters compiled under XCode 14 no longer specify
22
+ # this flag by default in DLDFLAGS. Let's specify the list of dynamic symbols
23
+ # here to avoid compilation failures.
24
+ if clang? && macos?
25
+ dynamic_symbols = %w[
26
+ _rb_cairo_surface_from_ruby_object
27
+ _rb_cairo_surface_to_ruby_object_with_destroy
28
+ _rbgobj_instance_from_ruby_object
29
+ _rbgobj_ruby_object_from_instance
30
+ ]
31
+ dynamic_symbols.each do |sym|
32
+ $DLDFLAGS << " -Wl,-U,#{sym.strip}"
33
+ end
34
+ end
35
+
36
+ %w[rbglib.h rbpango.h rcairo.h].each do |header|
37
+ Gem.find_files(header).each do |f|
38
+ $CFLAGS += " '-I#{File.dirname(f)}'"
39
+ end
40
+ end
41
+ # Look for headers in {gem_root}/ext/{package}
42
+ %w[glib2 cairo].each do |package|
43
+ require package
44
+ if Gem.loaded_specs[package]
45
+ $CFLAGS += " -I#{Gem.loaded_specs[package].full_gem_path}/ext/#{package}"
46
+ else
47
+ fn = $LOADED_FEATURES.find { |n| n.sub(/[.](so|rb)$/, '') == package }
48
+ if fn
49
+ dr = $LOAD_PATH.find { |d| File.exist?(File.join(d, fn)) }
50
+ pt = File.join(dr, fn) if dr && fn
51
+ else
52
+ pt = '??'
53
+ end
54
+ warn "require '#{package}' loaded '#{pt}' instead of the gem - trying to continue, but build may fail"
55
+ end
56
+ end
57
+ $CFLAGS += " -I#{RbConfig::CONFIG['rubyhdrdir']}/ruby" if RbConfig::CONFIG.key?('rubyhdrdir')
58
+
59
+ $CFLAGS += ' -I.'
60
+ have_func('rb_errinfo')
61
+ PKGConfig.have_package('gdk-pixbuf-2.0') or exit(-1)
62
+ # PKGConfig.have_package('gdk-2.0') or exit(-1)
63
+ PKGConfig.have_package('cairo') or exit(-1)
64
+
65
+ unless have_header('gdk-pixbuf/gdk-pixbuf.h')
66
+ paths = Gem.find_files('gdk-pixbuf/gdk-pixbuf.h')
67
+ paths.each do |path|
68
+ $CFLAGS += " '-I#{File.dirname(path)}'"
69
+ end
70
+ have_header('gdk-pixbuf/gdk-pixbuf.h') or exit(-1)
71
+ end
72
+
73
+ unless have_header('rbglib.h')
74
+ paths = Gem.find_files('rbglib.h')
75
+ paths.each do |path|
76
+ $CFLAGS += " '-I#{File.dirname(path)}'"
77
+ end
78
+ have_header('rbglib.h') or exit(-1)
79
+ end
80
+
81
+ unless have_header('rbgobject.h')
82
+ paths = Gem.find_files('rbgobject.h')
83
+ paths.each do |path|
84
+ $CFLAGS += " '-I#{File.dirname(path)}'"
85
+ end
86
+ have_header('rbgobject.h') or exit(-1)
87
+ end
88
+
89
+ $defs << '-DHAVE_OBJECT_ALLOCATE'
90
+
91
+ top = File.expand_path("#{File.dirname(__FILE__)}/..") # XXX
92
+ $CFLAGS << ' ' << ['glib/src'].map do |d|
93
+ "-I#{File.join(top, d)}"
94
+ end.join(' ')
95
+
96
+ begin
97
+ srcdir = File.expand_path(File.dirname($PROGRAM_NAME))
98
+
99
+ obj_ext = ".#{$OBJEXT}"
100
+ $libs = $libs.split(/ /).uniq.join(' ')
101
+ $source_files = Dir.glob(format('%s/*.c', srcdir)).map do |fname|
102
+ fname[0, srcdir.length + 1] = ''
103
+ fname
104
+ end
105
+ $objs = $source_files.collect do |item|
106
+ item.gsub(/.c$/, obj_ext)
107
+ end
108
+
109
+ #
110
+ # create Makefile
111
+ #
112
+ $defs << '-DRUBY_MORANDI_NATIVE_COMPILATION'
113
+ create_makefile('gdk_pixbuf_cairo', srcdir)
114
+ raise Interrupt unless FileTest.exist? 'Makefile'
115
+
116
+ File.open('Makefile', 'a') do |mfile|
117
+ $source_files.each do |e|
118
+ mfile.print("#{e.gsub(/.c$/, obj_ext)}: #{e}\n")
119
+ end
120
+ end
121
+ rescue Interrupt
122
+ print " [error] #{$ERROR_INFO}\n"
123
+ end
124
+ # rubocop:enable Style/GlobalVars
@@ -0,0 +1,260 @@
1
+ /* Includes */
2
+ #include <ruby.h>
3
+ #include <stdlib.h>
4
+ #include <stdio.h>
5
+ #include <string.h>
6
+
7
+ #if defined GCC
8
+ #define OPTIONAL_ATTR __attribute__((unused))
9
+ #else
10
+ #define OPTIONAL_ATTR
11
+ #endif
12
+
13
+ #include "gdk-pixbuf/gdk-pixbuf.h"
14
+ #include "rbglib.h"
15
+ #include "rbgobject.h"
16
+ #include "rb_cairo.h"
17
+
18
+ static VALUE mGdkPixbufCairo;
19
+ void Init_gdk_pixbuf_cairo(void);
20
+
21
+ /**
22
+ * pixbuf_cairo_create:
23
+ * @pixbuf: GdkPixbuf that you wish to wrap with cairo context
24
+ *
25
+ * This function will initialize new cairo context with contents of @pixbuf. You
26
+ * can then draw using returned context. When finished drawing, you must call
27
+ * pixbuf_cairo_destroy() or your pixbuf will not be updated with new contents!
28
+ *
29
+ * Return value: New cairo_t context. When you're done with it, call
30
+ * pixbuf_cairo_destroy() to update your pixbuf and free memory.
31
+ */
32
+ static cairo_surface_t *
33
+ pixbuf_to_surface(GdkPixbuf *pixbuf) {
34
+ gint width, /* Width of both pixbuf and surface */
35
+ height, /* Height of both pixbuf and surface */
36
+ p_stride, /* Pixbuf stride value */
37
+ p_n_channels, /* RGB -> 3, RGBA -> 4 */
38
+ s_stride, /* Surface stride value */
39
+ j;
40
+ guchar *p_pixels, /* Pixbuf's pixel data */
41
+ *s_pixels; /* Surface's pixel data */
42
+ cairo_surface_t *surface; /* Temporary image surface */
43
+
44
+ g_object_ref(G_OBJECT(pixbuf));
45
+
46
+ /* Inspect input pixbuf and create compatible cairo surface */
47
+ g_object_get(G_OBJECT(pixbuf), "width", &width,
48
+ "height", &height,
49
+ "rowstride", &p_stride,
50
+ "n-channels", &p_n_channels,
51
+ "pixels", &p_pixels,
52
+ NULL);
53
+ surface = cairo_image_surface_create(p_n_channels == 4 ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height);
54
+ s_stride = cairo_image_surface_get_stride(surface);
55
+ s_pixels = cairo_image_surface_get_data(surface);
56
+
57
+ /* Copy pixel data from pixbuf to surface */
58
+ for (j = height; j; j--) {
59
+ guchar *p = p_pixels;
60
+ guchar *q = s_pixels;
61
+
62
+ if (p_n_channels == 3) {
63
+ guchar *end = p + 3 * width;
64
+
65
+ while (p < end) {
66
+ #if G_BYTE_ORDER == G_LITTLE_ENDIAN
67
+ q[0] = p[2];
68
+ q[1] = p[1];
69
+ q[2] = p[0];
70
+ q[3] = 0xFF;
71
+ #else
72
+ q[0] = 0xFF;
73
+ q[1] = p[0];
74
+ q[2] = p[1];
75
+ q[3] = p[2];
76
+ #endif
77
+ p += 3;
78
+ q += 4;
79
+ }
80
+ } else {
81
+ guchar *end = p + 4 * width;
82
+ guint t1, t2, t3;
83
+
84
+ #define MULT(d, c, a, t) G_STMT_START { t = c * a + 0x80; d = ((t >> 8) + t) >> 8; } G_STMT_END
85
+
86
+ while (p < end) {
87
+ #if G_BYTE_ORDER == G_LITTLE_ENDIAN
88
+ MULT(q[0], p[2], p[3], t1);
89
+ MULT(q[1], p[1], p[3], t2);
90
+ MULT(q[2], p[0], p[3], t3);
91
+ q[3] = p[3];
92
+ #else
93
+ q[0] = p[3];
94
+ MULT(q[1], p[0], p[3], t1);
95
+ MULT(q[2], p[1], p[3], t2);
96
+ MULT(q[3], p[2], p[3], t3);
97
+ #endif
98
+
99
+ p += 4;
100
+ q += 4;
101
+ }
102
+
103
+ #undef MULT
104
+ }
105
+
106
+ p_pixels += p_stride;
107
+ s_pixels += s_stride;
108
+ }
109
+ g_object_unref(G_OBJECT(pixbuf));
110
+
111
+ cairo_surface_mark_dirty(surface);
112
+
113
+ return surface;
114
+ }
115
+
116
+ /**
117
+ * pixbuf_cairo_destroy:
118
+ * @cr: Cairo context that you wish to destroy
119
+ * @create_new_pixbuf: If TRUE, new pixbuf will be created and returned. If
120
+ * FALSE, input pixbuf will be updated in place.
121
+ *
122
+ * This function will destroy cairo context, created with pixbuf_cairo_create().
123
+ *
124
+ * Return value: New or updated GdkPixbuf. You own a new reference on return
125
+ * value, so you need to call g_object_unref() on returned pixbuf when you don't
126
+ * need it anymore.
127
+ */
128
+ static GdkPixbuf *
129
+ surface_to_pixbuf(cairo_surface_t *surface) {
130
+ gint width, /* Width of both pixbuf and surface */
131
+ height, /* Height of both pixbuf and surface */
132
+ p_stride, /* Pixbuf stride value */
133
+ p_n_channels, /* RGB -> 3, RGBA -> 4 */
134
+ s_stride, /* Surface stride value */
135
+ j;
136
+ guchar *p_pixels, /* Pixbuf's pixel data */
137
+ *s_pixels; /* Surface's pixel data */
138
+ GdkPixbuf *pixbuf; /* Pixbuf to be returned */
139
+ cairo_format_t format; /* cairo surface format */
140
+
141
+ format = cairo_image_surface_get_format(surface);
142
+
143
+ switch (format) {
144
+ case CAIRO_FORMAT_ARGB32:
145
+ p_n_channels = 4;
146
+ break;
147
+ case CAIRO_FORMAT_RGB24:
148
+ p_n_channels = 3;
149
+ break;
150
+ default:
151
+ return (GdkPixbuf *) 0;
152
+ break;
153
+ }
154
+
155
+ width = cairo_image_surface_get_width(surface);
156
+ height = cairo_image_surface_get_height(surface);
157
+ s_stride = cairo_image_surface_get_stride(surface);
158
+ s_pixels = cairo_image_surface_get_data(surface);
159
+
160
+ /* Create pixbuf to be returned */
161
+ pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, p_n_channels == 4, 8, width, height);
162
+
163
+ g_return_val_if_fail(pixbuf != NULL, NULL);
164
+
165
+ /* Inspect pixbuf and surface */
166
+ g_object_get(G_OBJECT(pixbuf),
167
+ "width", &width,
168
+ "height", &height,
169
+ "rowstride", &p_stride,
170
+ "n-channels", &p_n_channels,
171
+ "pixels", &p_pixels,
172
+ NULL);
173
+
174
+
175
+ /* Copy pixel data from surface to pixbuf */
176
+ for (j = height; j; j--) {
177
+ guchar *p = p_pixels;
178
+ guchar *q = s_pixels;
179
+
180
+ if (p_n_channels == 3) {
181
+ guchar *end = p + 3 * width;
182
+
183
+ while (p < end) {
184
+ #if G_BYTE_ORDER == G_LITTLE_ENDIAN
185
+ p[2] = q[0];
186
+ p[1] = q[1];
187
+ p[0] = q[2];
188
+ #else
189
+ p[0] = q[1];
190
+ p[1] = q[2];
191
+ p[2] = q[3];
192
+ #endif
193
+ p += 3;
194
+ q += 4;
195
+ }
196
+ } else {
197
+ guchar *end = p + 4 * width;
198
+ guint t1, t2, t3;
199
+
200
+ #define UNMULT(s_byte, p_byte, a, t) G_STMT_START { \
201
+ t = s_byte * 255 / a; \
202
+ p_byte = t; \
203
+ } G_STMT_END
204
+
205
+ while (p < end) {
206
+ #if G_BYTE_ORDER == G_LITTLE_ENDIAN
207
+ UNMULT(q[0], p[2], q[3], t1);
208
+ UNMULT(q[1], p[1], q[3], t2);
209
+ UNMULT(q[2], p[0], q[3], t3);
210
+ p[3] = q[3];
211
+ #else
212
+ p[3] = q[0];
213
+ UNMULT(q[1], p[0], q[3], t1);
214
+ UNMULT(q[2], p[1], q[3], t2);
215
+ UNMULT(q[3], p[2], q[3], t3);
216
+ #endif
217
+
218
+ p += 4;
219
+ q += 4;
220
+ }
221
+
222
+ #undef MULT
223
+ }
224
+
225
+ p_pixels += p_stride;
226
+ s_pixels += s_stride;
227
+ }
228
+
229
+ /* Return pixbuf */
230
+ return (pixbuf);
231
+ }
232
+
233
+ static
234
+ VALUE rb_pixbuf_to_surface(__attribute__((unused)) VALUE _self, VALUE pixbuf) {
235
+ cairo_surface_t *surface = pixbuf_to_surface(GDK_PIXBUF(RVAL2GOBJ(pixbuf)));
236
+ return CRSURFACE2RVAL_WITH_DESTROY(surface);
237
+ }
238
+
239
+ static
240
+ VALUE rb_surface_to_pixbuf(__attribute__((unused)) VALUE _self, VALUE surface) {
241
+ VALUE obj;
242
+ GdkPixbuf *pixbuf = surface_to_pixbuf(RVAL2CRSURFACE(surface));
243
+ if (pixbuf) {
244
+ obj = GOBJ2RVAL(pixbuf);
245
+ g_object_unref(pixbuf);
246
+ return obj;
247
+ }
248
+
249
+ rb_raise(rb_eRuntimeError, "Unable to convert Cairo::ImageSurface to Gdk::Pixbuf");
250
+
251
+ return Qnil;
252
+ }
253
+
254
+ /* Init */
255
+ void
256
+ Init_gdk_pixbuf_cairo(void) {
257
+ mGdkPixbufCairo = rb_define_module("GdkPixbufCairo");
258
+ rb_define_singleton_method(mGdkPixbufCairo, "pixbuf_to_surface", rb_pixbuf_to_surface, 1);
259
+ rb_define_singleton_method(mGdkPixbufCairo, "surface_to_pixbuf", rb_surface_to_pixbuf, 1);
260
+ }
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/GlobalVars
4
+ require 'mkmf'
5
+
6
+ require 'English'
7
+ require 'rubygems'
8
+ gem 'glib2'
9
+ require 'mkmf-gnome'
10
+
11
+ def macos?
12
+ !!(RUBY_PLATFORM =~ /darwin/)
13
+ end
14
+
15
+ def clang?
16
+ cc_version = `#{RbConfig.expand('$(CC) --version'.dup)}`
17
+ cc_version.match?(/clang/i)
18
+ end
19
+
20
+ # XCode 14 warns if `-Wl,-undefined dynamic_lookup` is specified, and as
21
+ # a result Ruby interpreters compiled under XCode 14 no longer specify
22
+ # this flag by default in DLDFLAGS. Let's specify the list of dynamic symbols
23
+ # here to avoid compilation failures.
24
+ if clang? && macos?
25
+ dynamic_symbols = %w[
26
+ _rbgobj_instance_from_ruby_object
27
+ _rbgobj_ruby_object_from_instance
28
+ ]
29
+ dynamic_symbols.each do |sym|
30
+ $DLDFLAGS << " -Wl,-U,#{sym.strip}"
31
+ end
32
+ end
33
+
34
+ %w[rbglib.h rbpango.h].each do |header|
35
+ Gem.find_files(header).each do |f|
36
+ $CFLAGS += " '-I#{File.dirname(f)}'"
37
+ end
38
+ end
39
+ # Look for headers in {gem_root}/ext/{package}
40
+ %w[glib2].each do |package|
41
+ require package
42
+ if Gem.loaded_specs[package]
43
+ $CFLAGS += " -I#{Gem.loaded_specs[package].full_gem_path}/ext/#{package}"
44
+ else
45
+ fn = $LOADED_FEATURES.find { |n| n.sub(/[.](so|rb)$/, '') == package }
46
+ if fn
47
+ dr = $LOAD_PATH.find { |d| File.exist?(File.join(d, fn)) }
48
+ pt = File.join(dr, fn) if dr && fn
49
+ else
50
+ pt = '??'
51
+ end
52
+ warn "require '#{package}' loaded '#{pt}' instead of the gem - trying to continue, but build may fail"
53
+ end
54
+ end
55
+ $CFLAGS += " -I#{RbConfig::CONFIG['rubyhdrdir']}/ruby" if RbConfig::CONFIG.key?('rubyhdrdir')
56
+
57
+ $CFLAGS += ' -I.'
58
+ have_func('rb_errinfo')
59
+ PKGConfig.have_package('gdk-pixbuf-2.0') or exit(-1)
60
+ # PKGConfig.have_package('gdk-2.0') or exit(-1)
61
+
62
+ unless have_header('gdk-pixbuf/gdk-pixbuf.h')
63
+ paths = Gem.find_files('gdk-pixbuf/gdk-pixbuf.h')
64
+ paths.each do |path|
65
+ $CFLAGS += " '-I#{File.dirname(path)}'"
66
+ end
67
+ have_header('gdk-pixbuf/gdk-pixbuf.h') or exit(-1)
68
+ end
69
+
70
+ unless have_header('rbglib.h')
71
+ paths = Gem.find_files('rbglib.h')
72
+ paths.each do |path|
73
+ $CFLAGS += " '-I#{File.dirname(path)}'"
74
+ end
75
+ have_header('rbglib.h') or exit(-1)
76
+ end
77
+
78
+ unless have_header('rbgobject.h')
79
+ paths = Gem.find_files('rbgobject.h')
80
+ paths.each do |path|
81
+ $CFLAGS += " '-I#{File.dirname(path)}'"
82
+ end
83
+ have_header('rbgobject.h') or exit(-1)
84
+ end
85
+
86
+ $defs << '-DHAVE_OBJECT_ALLOCATE'
87
+
88
+ top = File.expand_path("#{File.dirname(__FILE__)}/..") # XXX
89
+ $CFLAGS << ' ' << ['glib/src'].map do |d|
90
+ "-I#{File.join(top, d)}"
91
+ end.join(' ')
92
+
93
+ begin
94
+ srcdir = File.expand_path(File.dirname($PROGRAM_NAME))
95
+
96
+ obj_ext = ".#{$OBJEXT}"
97
+ $libs = $libs.split(/ /).uniq.join(' ')
98
+ $source_files = Dir.glob(format('%s/*.c', srcdir)).map do |fname|
99
+ fname[0, srcdir.length + 1] = ''
100
+ fname
101
+ end
102
+ $objs = $source_files.collect do |item|
103
+ item.gsub(/.c$/, obj_ext)
104
+ end
105
+
106
+ #
107
+ # create Makefile
108
+ #
109
+ $defs << '-DRUBY_MORANDI_NATIVE_COMPILATION'
110
+ create_makefile('morandi_native', srcdir)
111
+ raise Interrupt unless FileTest.exist? 'Makefile'
112
+
113
+ File.open('Makefile', 'a') do |mfile|
114
+ $source_files.each do |e|
115
+ mfile.print("#{e.gsub(/.c$/, obj_ext)}: #{e}\n")
116
+ end
117
+ end
118
+ rescue Interrupt
119
+ print " [error] #{$ERROR_INFO}\n"
120
+ end
121
+ # rubocop:enable Style/GlobalVars