cairo 1.8.3-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of cairo might be problematic. Click here for more details.
- data/AUTHORS +4 -0
- data/COPYING +59 -0
- data/GPL +340 -0
- data/NEWS +163 -0
- data/Rakefile +190 -0
- data/doc/doc.css +91 -0
- data/doc/en/cairo-antialias.html +38 -0
- data/doc/en/cairo-clip-not-representable-error.html +47 -0
- data/doc/en/cairo-color-base.html +69 -0
- data/doc/en/cairo-color-cmyk.html +157 -0
- data/doc/en/cairo-color-hsv.html +137 -0
- data/doc/en/cairo-color-rgb.html +142 -0
- data/doc/en/cairo-color-x11.html +173 -0
- data/doc/en/cairo-color.html +238 -0
- data/doc/en/cairo-content.html +37 -0
- data/doc/en/cairo-context-blur.html +39 -0
- data/doc/en/cairo-context-circle.html +39 -0
- data/doc/en/cairo-context-color.html +39 -0
- data/doc/en/cairo-context-path.html +44 -0
- data/doc/en/cairo-context-rectangle.html +39 -0
- data/doc/en/cairo-context-triangle.html +39 -0
- data/doc/en/cairo-context.html +643 -0
- data/doc/en/cairo-error.html +44 -0
- data/doc/en/cairo-extend.html +38 -0
- data/doc/en/cairo-file-not-found.html +47 -0
- data/doc/en/cairo-fill-rule.html +36 -0
- data/doc/en/cairo-filter.html +40 -0
- data/doc/en/cairo-font-extents.html +129 -0
- data/doc/en/cairo-font-face.html +38 -0
- data/doc/en/cairo-font-options.html +139 -0
- data/doc/en/cairo-font-slant.html +37 -0
- data/doc/en/cairo-font-type-mismatch.html +47 -0
- data/doc/en/cairo-font-weight.html +36 -0
- data/doc/en/cairo-format.html +46 -0
- data/doc/en/cairo-glyph.html +99 -0
- data/doc/en/cairo-gradient-pattern.html +74 -0
- data/doc/en/cairo-hint-metrics.html +37 -0
- data/doc/en/cairo-hint-style.html +39 -0
- data/doc/en/cairo-image-surface.html +82 -0
- data/doc/en/cairo-invalid-clusters.html +47 -0
- data/doc/en/cairo-invalid-content-error.html +47 -0
- data/doc/en/cairo-invalid-dash-error.html +47 -0
- data/doc/en/cairo-invalid-dsc-comment-error.html +47 -0
- data/doc/en/cairo-invalid-format-error.html +47 -0
- data/doc/en/cairo-invalid-index-error.html +47 -0
- data/doc/en/cairo-invalid-matrix-error.html +47 -0
- data/doc/en/cairo-invalid-path-data-error.html +47 -0
- data/doc/en/cairo-invalid-pop-group-error.html +47 -0
- data/doc/en/cairo-invalid-restore-error.html +47 -0
- data/doc/en/cairo-invalid-slant.html +47 -0
- data/doc/en/cairo-invalid-status-error.html +47 -0
- data/doc/en/cairo-invalid-stride-error.html +47 -0
- data/doc/en/cairo-invalid-string-error.html +47 -0
- data/doc/en/cairo-invalid-visual-error.html +47 -0
- data/doc/en/cairo-invalid-weight.html +47 -0
- data/doc/en/cairo-line-cap.html +37 -0
- data/doc/en/cairo-line-join.html +37 -0
- data/doc/en/cairo-linear-pattern.html +60 -0
- data/doc/en/cairo-matrix.html +259 -0
- data/doc/en/cairo-negative-count.html +47 -0
- data/doc/en/cairo-no-current-point-error.html +47 -0
- data/doc/en/cairo-null-pointer-error.html +47 -0
- data/doc/en/cairo-operator.html +48 -0
- data/doc/en/cairo-paper-parse-error.html +47 -0
- data/doc/en/cairo-paper-unknown-paper-name.html +66 -0
- data/doc/en/cairo-paper-unknown-unit.html +66 -0
- data/doc/en/cairo-paper-unrecognized-paper-description.html +66 -0
- data/doc/en/cairo-paper.html +184 -0
- data/doc/en/cairo-path-close-path.html +49 -0
- data/doc/en/cairo-path-curve-to.html +49 -0
- data/doc/en/cairo-path-data-type.html +38 -0
- data/doc/en/cairo-path-data.html +98 -0
- data/doc/en/cairo-path-line-to.html +49 -0
- data/doc/en/cairo-path-move-to.html +49 -0
- data/doc/en/cairo-path.html +155 -0
- data/doc/en/cairo-pattern-type-mismatch-error.html +47 -0
- data/doc/en/cairo-pattern.html +99 -0
- data/doc/en/cairo-pdf-surface.html +57 -0
- data/doc/en/cairo-point.html +74 -0
- data/doc/en/cairo-ps-level.html +49 -0
- data/doc/en/cairo-ps-surface.html +92 -0
- data/doc/en/cairo-quartz-image-surface.html +57 -0
- data/doc/en/cairo-quartz-surface.html +57 -0
- data/doc/en/cairo-radial-pattern.html +60 -0
- data/doc/en/cairo-read-error.html +47 -0
- data/doc/en/cairo-rectangle.html +89 -0
- data/doc/en/cairo-scaled-font.html +94 -0
- data/doc/en/cairo-solid-pattern.html +62 -0
- data/doc/en/cairo-subpixel-order.html +39 -0
- data/doc/en/cairo-surface-finished-error.html +47 -0
- data/doc/en/cairo-surface-pattern.html +57 -0
- data/doc/en/cairo-surface-type-mismatch-error.html +47 -0
- data/doc/en/cairo-surface.html +121 -0
- data/doc/en/cairo-svg-surface.html +77 -0
- data/doc/en/cairo-svg-version.html +49 -0
- data/doc/en/cairo-temp-file-error.html +47 -0
- data/doc/en/cairo-text-cluster-flag.html +35 -0
- data/doc/en/cairo-text-cluster.html +84 -0
- data/doc/en/cairo-text-extents.html +144 -0
- data/doc/en/cairo-toy-font-face.html +67 -0
- data/doc/en/cairo-user-font-error.html +47 -0
- data/doc/en/cairo-user-font-face-text-to-glyphs-data.html +94 -0
- data/doc/en/cairo-user-font-face.html +72 -0
- data/doc/en/cairo-user-font-immutable.html +47 -0
- data/doc/en/cairo-win32-printing-surface.html +57 -0
- data/doc/en/cairo-win32-surface.html +62 -0
- data/doc/en/cairo-write-error.html +47 -0
- data/doc/en/cairo.html +131 -0
- data/doc/en/index.html +1154 -0
- data/doc/index.html +18 -0
- data/doc/ja/cairo-antialias.html +57 -0
- data/doc/ja/cairo-clip-not-representable-error.html +56 -0
- data/doc/ja/cairo-color-base.html +75 -0
- data/doc/ja/cairo-color-cmyk.html +152 -0
- data/doc/ja/cairo-color-hsv.html +135 -0
- data/doc/ja/cairo-color-rgb.html +145 -0
- data/doc/ja/cairo-color-x11.html +183 -0
- data/doc/ja/cairo-color.html +317 -0
- data/doc/ja/cairo-content.html +51 -0
- data/doc/ja/cairo-context-blur.html +53 -0
- data/doc/ja/cairo-context-circle.html +54 -0
- data/doc/ja/cairo-context-color.html +52 -0
- data/doc/ja/cairo-context-path.html +77 -0
- data/doc/ja/cairo-context-rectangle.html +60 -0
- data/doc/ja/cairo-context-triangle.html +47 -0
- data/doc/ja/cairo-context.html +1542 -0
- data/doc/ja/cairo-error.html +56 -0
- data/doc/ja/cairo-extend.html +56 -0
- data/doc/ja/cairo-file-not-found.html +51 -0
- data/doc/ja/cairo-fill-rule.html +58 -0
- data/doc/ja/cairo-filter.html +43 -0
- data/doc/ja/cairo-font-extents.html +164 -0
- data/doc/ja/cairo-font-face.html +55 -0
- data/doc/ja/cairo-font-options.html +189 -0
- data/doc/ja/cairo-font-slant.html +50 -0
- data/doc/ja/cairo-font-type-mismatch.html +52 -0
- data/doc/ja/cairo-font-weight.html +47 -0
- data/doc/ja/cairo-format.html +81 -0
- data/doc/ja/cairo-glyph.html +115 -0
- data/doc/ja/cairo-gradient-pattern.html +119 -0
- data/doc/ja/cairo-hint-metrics.html +57 -0
- data/doc/ja/cairo-hint-style.html +64 -0
- data/doc/ja/cairo-image-surface.html +131 -0
- data/doc/ja/cairo-invalid-clusters.html +55 -0
- data/doc/ja/cairo-invalid-content-error.html +54 -0
- data/doc/ja/cairo-invalid-dash-error.html +54 -0
- data/doc/ja/cairo-invalid-dsc-comment-error.html +54 -0
- data/doc/ja/cairo-invalid-format-error.html +54 -0
- data/doc/ja/cairo-invalid-index-error.html +54 -0
- data/doc/ja/cairo-invalid-matrix-error.html +54 -0
- data/doc/ja/cairo-invalid-path-data-error.html +54 -0
- data/doc/ja/cairo-invalid-pop-group-error.html +54 -0
- data/doc/ja/cairo-invalid-restore-error.html +55 -0
- data/doc/ja/cairo-invalid-slant.html +57 -0
- data/doc/ja/cairo-invalid-status-error.html +55 -0
- data/doc/ja/cairo-invalid-stride-error.html +55 -0
- data/doc/ja/cairo-invalid-string-error.html +54 -0
- data/doc/ja/cairo-invalid-visual-error.html +57 -0
- data/doc/ja/cairo-invalid-weight.html +57 -0
- data/doc/ja/cairo-line-cap.html +50 -0
- data/doc/ja/cairo-line-join.html +53 -0
- data/doc/ja/cairo-linear-pattern.html +87 -0
- data/doc/ja/cairo-matrix.html +354 -0
- data/doc/ja/cairo-negative-count.html +52 -0
- data/doc/ja/cairo-no-current-point-error.html +54 -0
- data/doc/ja/cairo-null-pointer-error.html +54 -0
- data/doc/ja/cairo-operator.html +51 -0
- data/doc/ja/cairo-paper-parse-error.html +55 -0
- data/doc/ja/cairo-paper-unknown-paper-name.html +76 -0
- data/doc/ja/cairo-paper-unknown-unit.html +75 -0
- data/doc/ja/cairo-paper-unrecognized-paper-description.html +76 -0
- data/doc/ja/cairo-paper.html +357 -0
- data/doc/ja/cairo-path-close-path.html +57 -0
- data/doc/ja/cairo-path-curve-to.html +70 -0
- data/doc/ja/cairo-path-data-type.html +53 -0
- data/doc/ja/cairo-path-data.html +127 -0
- data/doc/ja/cairo-path-line-to.html +62 -0
- data/doc/ja/cairo-path-move-to.html +62 -0
- data/doc/ja/cairo-path.html +144 -0
- data/doc/ja/cairo-pattern-type-mismatch-error.html +56 -0
- data/doc/ja/cairo-pattern.html +128 -0
- data/doc/ja/cairo-pdf-surface.html +86 -0
- data/doc/ja/cairo-point.html +90 -0
- data/doc/ja/cairo-ps-level.html +62 -0
- data/doc/ja/cairo-ps-surface.html +214 -0
- data/doc/ja/cairo-quartz-image-surface.html +75 -0
- data/doc/ja/cairo-quartz-surface.html +93 -0
- data/doc/ja/cairo-radial-pattern.html +93 -0
- data/doc/ja/cairo-read-error.html +55 -0
- data/doc/ja/cairo-rectangle.html +109 -0
- data/doc/ja/cairo-scaled-font.html +180 -0
- data/doc/ja/cairo-solid-pattern.html +87 -0
- data/doc/ja/cairo-subpixel-order.html +57 -0
- data/doc/ja/cairo-surface-finished-error.html +54 -0
- data/doc/ja/cairo-surface-pattern.html +68 -0
- data/doc/ja/cairo-surface-type-mismatch-error.html +56 -0
- data/doc/ja/cairo-surface.html +213 -0
- data/doc/ja/cairo-svg-surface.html +114 -0
- data/doc/ja/cairo-svg-version.html +66 -0
- data/doc/ja/cairo-temp-file-error.html +50 -0
- data/doc/ja/cairo-text-cluster-flag.html +46 -0
- data/doc/ja/cairo-text-cluster.html +102 -0
- data/doc/ja/cairo-text-extents.html +163 -0
- data/doc/ja/cairo-toy-font-face.html +107 -0
- data/doc/ja/cairo-user-font-error.html +55 -0
- data/doc/ja/cairo-user-font-face-text-to-glyphs-data.html +156 -0
- data/doc/ja/cairo-user-font-face.html +268 -0
- data/doc/ja/cairo-user-font-immutable.html +54 -0
- data/doc/ja/cairo-win32-printing-surface.html +80 -0
- data/doc/ja/cairo-win32-surface.html +100 -0
- data/doc/ja/cairo-write-error.html +55 -0
- data/doc/ja/cairo.html +177 -0
- data/doc/ja/index.html +1156 -0
- data/ext/cairo/cairo.def +104 -0
- data/ext/cairo/extconf.rb +80 -0
- data/ext/cairo/rb_cairo.c +104 -0
- data/ext/cairo/rb_cairo.h +275 -0
- data/ext/cairo/rb_cairo_constants.c +478 -0
- data/ext/cairo/rb_cairo_context.c +1693 -0
- data/ext/cairo/rb_cairo_exception.c +354 -0
- data/ext/cairo/rb_cairo_font_extents.c +200 -0
- data/ext/cairo/rb_cairo_font_face.c +713 -0
- data/ext/cairo/rb_cairo_font_options.c +197 -0
- data/ext/cairo/rb_cairo_glyph.c +161 -0
- data/ext/cairo/rb_cairo_matrix.c +366 -0
- data/ext/cairo/rb_cairo_path.c +459 -0
- data/ext/cairo/rb_cairo_pattern.c +540 -0
- data/ext/cairo/rb_cairo_private.c +242 -0
- data/ext/cairo/rb_cairo_private.h +114 -0
- data/ext/cairo/rb_cairo_scaled_font.c +235 -0
- data/ext/cairo/rb_cairo_surface.c +1371 -0
- data/ext/cairo/rb_cairo_text_cluster.c +151 -0
- data/ext/cairo/rb_cairo_text_extents.c +221 -0
- data/extconf.rb +45 -0
- data/lib/1.8/cairo.so +0 -0
- data/lib/1.9/cairo.so +0 -0
- data/lib/cairo.rb +151 -0
- data/lib/cairo/color.rb +267 -0
- data/lib/cairo/colors.rb +656 -0
- data/lib/cairo/constants.rb +24 -0
- data/lib/cairo/context.rb +29 -0
- data/lib/cairo/context/blur.rb +45 -0
- data/lib/cairo/context/circle.rb +9 -0
- data/lib/cairo/context/color.rb +11 -0
- data/lib/cairo/context/path.rb +116 -0
- data/lib/cairo/context/rectangle.rb +33 -0
- data/lib/cairo/context/triangle.rb +12 -0
- data/lib/cairo/paper.rb +183 -0
- data/lib/cairo/papers.rb +41 -0
- data/lib/cairo/path.rb +15 -0
- data/lib/cairo/point.rb +7 -0
- data/misc/update-colors.rb +143 -0
- data/pkg-config.rb +313 -0
- data/samples/agg/README +4 -0
- data/samples/agg/aa_test.rb +304 -0
- data/samples/blur.rb +47 -0
- data/samples/pac.rb +99 -0
- data/samples/pac2.rb +171 -0
- data/samples/png.rb +45 -0
- data/samples/scalable.rb +56 -0
- data/samples/text-on-path.rb +60 -0
- data/samples/text2.rb +131 -0
- data/test-unit/Rakefile +30 -0
- data/test-unit/bin/testrb +5 -0
- data/test-unit/lib/test/unit.rb +280 -0
- data/test-unit/lib/test/unit/assertionfailederror.rb +14 -0
- data/test-unit/lib/test/unit/assertions.rb +722 -0
- data/test-unit/lib/test/unit/attribute.rb +125 -0
- data/test-unit/lib/test/unit/autorunner.rb +254 -0
- data/test-unit/lib/test/unit/collector.rb +43 -0
- data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
- data/test-unit/lib/test/unit/collector/dir.rb +108 -0
- data/test-unit/lib/test/unit/collector/load.rb +135 -0
- data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
- data/test-unit/lib/test/unit/color.rb +61 -0
- data/test-unit/lib/test/unit/diff.rb +524 -0
- data/test-unit/lib/test/unit/error.rb +124 -0
- data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
- data/test-unit/lib/test/unit/failure.rb +110 -0
- data/test-unit/lib/test/unit/fixture.rb +185 -0
- data/test-unit/lib/test/unit/notification.rb +125 -0
- data/test-unit/lib/test/unit/omission.rb +143 -0
- data/test-unit/lib/test/unit/pending.rb +146 -0
- data/test-unit/lib/test/unit/priority.rb +146 -0
- data/test-unit/lib/test/unit/runner/console.rb +46 -0
- data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
- data/test-unit/lib/test/unit/testcase.rb +281 -0
- data/test-unit/lib/test/unit/testresult.rb +89 -0
- data/test-unit/lib/test/unit/testsuite.rb +110 -0
- data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
- data/test-unit/lib/test/unit/ui/console/testrunner.rb +195 -0
- data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +49 -0
- data/test-unit/lib/test/unit/ui/testrunner.rb +20 -0
- data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
- data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
- data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
- data/test-unit/lib/test/unit/util/observable.rb +90 -0
- data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
- data/test-unit/lib/test/unit/version.rb +7 -0
- data/test-unit/sample/adder.rb +13 -0
- data/test-unit/sample/subtracter.rb +12 -0
- data/test-unit/sample/tc_adder.rb +18 -0
- data/test-unit/sample/tc_subtracter.rb +18 -0
- data/test-unit/sample/ts_examples.rb +7 -0
- data/test-unit/test/collector/test_descendant.rb +135 -0
- data/test-unit/test/collector/test_dir.rb +406 -0
- data/test-unit/test/collector/test_load.rb +333 -0
- data/test-unit/test/collector/test_objectspace.rb +98 -0
- data/test-unit/test/run-test.rb +13 -0
- data/test-unit/test/test_assertions.rb +693 -0
- data/test-unit/test/test_attribute.rb +86 -0
- data/test-unit/test/test_color.rb +37 -0
- data/test-unit/test/test_diff.rb +477 -0
- data/test-unit/test/test_emacs_runner.rb +60 -0
- data/test-unit/test/test_error.rb +26 -0
- data/test-unit/test/test_failure.rb +33 -0
- data/test-unit/test/test_fixture.rb +252 -0
- data/test-unit/test/test_notification.rb +33 -0
- data/test-unit/test/test_omission.rb +81 -0
- data/test-unit/test/test_pending.rb +70 -0
- data/test-unit/test/test_priority.rb +89 -0
- data/test-unit/test/test_testcase.rb +430 -0
- data/test-unit/test/test_testresult.rb +113 -0
- data/test-unit/test/test_testsuite.rb +129 -0
- data/test-unit/test/testunit_test_util.rb +14 -0
- data/test-unit/test/ui/test_testrunmediator.rb +20 -0
- data/test-unit/test/util/test_backtracefilter.rb +41 -0
- data/test-unit/test/util/test_observable.rb +102 -0
- data/test-unit/test/util/test_procwrapper.rb +36 -0
- data/test/cairo-test-utils.rb +18 -0
- data/test/run-test.rb +28 -0
- data/test/test_color.rb +17 -0
- data/test/test_constants.rb +16 -0
- data/test/test_context.rb +105 -0
- data/test/test_exception.rb +27 -0
- data/test/test_font_extents.rb +36 -0
- data/test/test_font_face.rb +244 -0
- data/test/test_font_options.rb +13 -0
- data/test/test_paper.rb +81 -0
- data/test/test_pkg_config.rb +123 -0
- data/test/test_scaled_font.rb +34 -0
- data/test/test_surface.rb +41 -0
- data/test/test_text_cluster.rb +32 -0
- data/test/test_text_extents.rb +40 -0
- data/test/test_text_to_glyphs_data.rb +51 -0
- data/tmp/x86-mingw32/cairo/1.8.7/fake.rb +6 -0
- data/tmp/x86-mingw32/cairo/1.8.7/mkmf.rb +1836 -0
- data/tmp/x86-mingw32/cairo/1.8.7/rbconfig.rb +183 -0
- data/tmp/x86-mingw32/cairo/1.9.2/fake.rb +6 -0
- data/tmp/x86-mingw32/cairo/1.9.2/mkmf.rb +2079 -0
- data/tmp/x86-mingw32/cairo/1.9.2/rbconfig.rb +226 -0
- metadata +437 -0
data/test/test_paper.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'cairo'
|
2
|
+
|
3
|
+
class PaperTest < Test::Unit::TestCase
|
4
|
+
def test_parse_paper
|
5
|
+
a4 = Cairo::Paper::A4
|
6
|
+
assert_parse(a4, a4)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_parse_name
|
10
|
+
assert_parse(:A4, "A4")
|
11
|
+
assert_parse(:A4_LANDSCAPE, "A4 landscape")
|
12
|
+
assert_parse(:A4, :A4)
|
13
|
+
assert_parse(:A4, :a4)
|
14
|
+
|
15
|
+
assert_parse(:JAPANESE_POSTCARD, :japanese_postcard)
|
16
|
+
assert_parse(:JAPANESE_POSTCARD, "japanese-postcard")
|
17
|
+
assert_parse(:JAPANESE_POSTCARD, "Japanese postcard")
|
18
|
+
|
19
|
+
exception = assert_raise(Cairo::Paper::UnknownPaperName) do
|
20
|
+
Cairo::Paper.parse(:nonexistence)
|
21
|
+
end
|
22
|
+
assert_equal(:nonexistence, exception.name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_parse_size
|
26
|
+
assert_parse(paper(100, 200), "100x200")
|
27
|
+
assert_parse(paper(283.46456664, 566.929134), "100mmx200mm")
|
28
|
+
assert_parse(paper(284.88188952, 200.9), "100.5mmx200.9")
|
29
|
+
assert_parse(paper(72, 612.0), "1inx8.5inch")
|
30
|
+
assert_parse(paper(28.346456664, 24094.488168), "1cmx8.5m")
|
31
|
+
assert_parse(paper(100, 200), [100, 200])
|
32
|
+
|
33
|
+
exception = assert_raise(Cairo::Paper::UnknownUnit) do
|
34
|
+
Cairo::Paper.parse("100kmx100")
|
35
|
+
end
|
36
|
+
assert_equal("km", exception.unit)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_parse_size_with_name
|
40
|
+
assert_parse(paper(28.346456664, 24094.488168, nil, "Name"),
|
41
|
+
"1cmx8.5m#Name")
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_unrecognized_input
|
45
|
+
assert_nothing_raised do
|
46
|
+
Cairo::Paper.parse({})
|
47
|
+
end
|
48
|
+
|
49
|
+
exception = assert_raise(Cairo::Paper::UnrecognizedPaperDescription) do
|
50
|
+
Cairo::Paper.parse({}, true)
|
51
|
+
end
|
52
|
+
assert_equal({}, exception.description)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_unit
|
56
|
+
paper = parse("1cmx8.5m")
|
57
|
+
assert_nil(paper.unit)
|
58
|
+
assert_in_delta(28.346456664, 0.01, paper.width)
|
59
|
+
assert_in_delta(24094.488168, 0.01, paper.height)
|
60
|
+
|
61
|
+
paper.unit = "inch"
|
62
|
+
assert_equal("inch", paper.unit)
|
63
|
+
assert_in_delta(0.393700787, 0.01, paper.width)
|
64
|
+
assert_in_delta(334.645669, 0.01, paper.height)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def paper(width, height, *rest)
|
69
|
+
Cairo::Paper.new(width, height, *rest)
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse(paper_description)
|
73
|
+
Cairo::Paper.parse(paper_description)
|
74
|
+
end
|
75
|
+
|
76
|
+
def assert_parse(expected, paper_description, message=nil)
|
77
|
+
expected = Cairo::Paper.const_get(expected) if expected.is_a?(Symbol)
|
78
|
+
actual_paper = parse(paper_description)
|
79
|
+
assert_equal(expected, actual_paper, message)
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'pkg-config'
|
2
|
+
|
3
|
+
class PkgConfigTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@cairo = PackageConfig.new("cairo")
|
6
|
+
@cairo_png = PackageConfig.new("cairo-png")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_exist?
|
10
|
+
assert(system('pkg-config --exists cairo'))
|
11
|
+
assert(@cairo.exist?)
|
12
|
+
|
13
|
+
assert(system('pkg-config --exists cairo-png'))
|
14
|
+
assert(@cairo_png.exist?)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_cflags
|
18
|
+
assert_pkg_config("cairo", ["--cflags"], @cairo.cflags)
|
19
|
+
assert_pkg_config("cairo-png", ["--cflags"], @cairo_png.cflags)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_cflags_only_I
|
23
|
+
assert_pkg_config("cairo", ["--cflags-only-I"], @cairo.cflags_only_I)
|
24
|
+
assert_pkg_config("cairo-png", ["--cflags-only-I"], @cairo_png.cflags_only_I)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_libs
|
28
|
+
assert_pkg_config("cairo", ["--libs"], @cairo.libs)
|
29
|
+
assert_pkg_config("cairo-png", ["--libs"], @cairo_png.libs)
|
30
|
+
|
31
|
+
@cairo.msvc_syntax = true
|
32
|
+
result = pkg_config("cairo", "--libs")
|
33
|
+
msvc_result = result.gsub(/-lcairo\b/, "cairo.lib")
|
34
|
+
assert_not_equal(msvc_result, result)
|
35
|
+
assert_equal(msvc_result, @cairo.libs)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_libs_only_l
|
39
|
+
assert_pkg_config("cairo", ["--libs-only-l"], @cairo.libs_only_l)
|
40
|
+
assert_pkg_config("cairo-png", ["--libs-only-l"], @cairo_png.libs_only_l)
|
41
|
+
|
42
|
+
@cairo_png.msvc_syntax = true
|
43
|
+
result = pkg_config("cairo-png", "--libs-only-l")
|
44
|
+
msvc_result = result.gsub(/-l(cairo|png12)\b/, '\1.lib')
|
45
|
+
assert_not_equal(msvc_result, result)
|
46
|
+
assert_equal(msvc_result, @cairo_png.libs_only_l)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_requires
|
50
|
+
assert_equal([], @cairo.requires)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_requires_private
|
54
|
+
assert_equal(["freetype2", "fontconfig", "libpng12",
|
55
|
+
"xcb", "xcb-render", "xcb-renderutil",
|
56
|
+
"xrender", "x11", "pixman-1"],
|
57
|
+
@cairo.requires_private)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_version
|
61
|
+
assert_pkg_config("cairo", ["--modversion"], @cairo.version)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_parse_override_variables
|
65
|
+
assert_override_variables({}, nil)
|
66
|
+
assert_override_variables({"prefix" => "c:\\\\gtk-dev"},
|
67
|
+
"prefix=c:\\\\gtk-dev")
|
68
|
+
assert_override_variables({
|
69
|
+
"prefix" => "c:\\\\gtk-dev",
|
70
|
+
"includdir" => "d:\\\\gtk\\include"
|
71
|
+
},
|
72
|
+
["prefix=c:\\\\gtk-dev",
|
73
|
+
"includdir=d:\\\\gtk\\include"].join(","))
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_override_variables
|
77
|
+
overridden_prefix = "c:\\\\gtk-dev"
|
78
|
+
original_prefix = @cairo.variable("prefix")
|
79
|
+
assert_not_equal(overridden_prefix, original_prefix)
|
80
|
+
with_override_variables("prefix=#{overridden_prefix}") do
|
81
|
+
cairo = PackageConfig.new("cairo")
|
82
|
+
assert_equal(overridden_prefix, cairo.variable("prefix"))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def pkg_config(package, *args)
|
88
|
+
args = args.collect {|arg| arg.dump}.join(' ')
|
89
|
+
`pkg-config #{args} #{package}`.strip
|
90
|
+
end
|
91
|
+
|
92
|
+
def assert_pkg_config(package, pkg_config_args, actual)
|
93
|
+
result = pkg_config(package, *pkg_config_args)
|
94
|
+
result = nil if result.empty?
|
95
|
+
assert_equal(result, actual)
|
96
|
+
end
|
97
|
+
|
98
|
+
def assert_override_variables(expected, override_variables)
|
99
|
+
with_override_variables(override_variables) do
|
100
|
+
cairo = PackageConfig.new("cairo")
|
101
|
+
assert_equal(expected, cairo.instance_variable_get("@override_variables"))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def with_override_variables(override_variables)
|
106
|
+
if override_variables.nil?
|
107
|
+
args = {}
|
108
|
+
else
|
109
|
+
args = {"--with-override-variables" => override_variables}
|
110
|
+
end
|
111
|
+
configure_args(args) do
|
112
|
+
yield
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def configure_args(args)
|
117
|
+
original_configure_args = $configure_args
|
118
|
+
$configure_args = $configure_args.merge(args)
|
119
|
+
yield
|
120
|
+
ensure
|
121
|
+
$configure_args = original_configure_args
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'cairo'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class ScaledFontTest < Test::Unit::TestCase
|
5
|
+
include CairoTestUtils
|
6
|
+
|
7
|
+
def test_scale_matrix
|
8
|
+
only_cairo_version(1, 7, 2)
|
9
|
+
|
10
|
+
surface = Cairo::ImageSurface.new(100, 100)
|
11
|
+
context = Cairo::Context.new(surface)
|
12
|
+
scaled_font = context.scaled_font
|
13
|
+
|
14
|
+
assert_equal(Cairo::Matrix.new(10.0, 0.0, 0.0,
|
15
|
+
10.0, 0.0, 0.0),
|
16
|
+
scaled_font.scale_matrix)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_text_to_glyphs
|
20
|
+
only_cairo_version(1, 7, 6)
|
21
|
+
|
22
|
+
surface = Cairo::PDFSurface.new(StringIO.new, 10, 10)
|
23
|
+
context = Cairo::Context.new(surface)
|
24
|
+
scaled_font = Cairo::ScaledFont.new(context.font_face,
|
25
|
+
Cairo::Matrix.identity,
|
26
|
+
Cairo::Matrix.identity,
|
27
|
+
Cairo::FontOptions.new)
|
28
|
+
expected_glyphs = []
|
29
|
+
expected_clusters = []
|
30
|
+
expected_cluster_flags = 0
|
31
|
+
assert_equal([expected_glyphs, expected_clusters, expected_cluster_flags],
|
32
|
+
scaled_font.text_to_glyphs(0, 0, "text"))
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'cairo'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class SurfaceTest < Test::Unit::TestCase
|
5
|
+
include CairoTestUtils
|
6
|
+
|
7
|
+
def test_new
|
8
|
+
output = StringIO.new
|
9
|
+
surface = Cairo::PDFSurface.new(output, 10, 10)
|
10
|
+
assert_no_match(/%%EOF\s*\z/m, output.string)
|
11
|
+
surface.finish
|
12
|
+
assert_match(/%%EOF\s*\z/m, output.string)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_new_with_block
|
16
|
+
output = StringIO.new
|
17
|
+
Cairo::PDFSurface.new(output, 10, 10) do |surface|
|
18
|
+
assert_no_match(/%%EOF\s*\z/m, output.string)
|
19
|
+
end
|
20
|
+
assert_match(/%%EOF\s*\z/m, output.string)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_new_with_block_and_finish
|
24
|
+
assert_nothing_raised do
|
25
|
+
Cairo::PDFSurface.new(StringIO.new, 10, 10) do |surface|
|
26
|
+
surface.finish
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_fallback_resolution
|
32
|
+
only_cairo_version(1, 7, 2)
|
33
|
+
|
34
|
+
surface = Cairo::ImageSurface.new(100, 100)
|
35
|
+
|
36
|
+
assert_equal([300.0, 300.0], surface.fallback_resolution)
|
37
|
+
|
38
|
+
surface.set_fallback_resolution(95, 95)
|
39
|
+
assert_equal([95.0, 95.0], surface.fallback_resolution)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'cairo'
|
2
|
+
|
3
|
+
class TextClusterTest < Test::Unit::TestCase
|
4
|
+
include CairoTestUtils
|
5
|
+
|
6
|
+
def test_new
|
7
|
+
only_cairo_version(1, 7, 2)
|
8
|
+
|
9
|
+
cluster = Cairo::TextCluster.new(2, 3)
|
10
|
+
assert_equal([2, 3], [cluster.num_bytes, cluster.num_glyphs])
|
11
|
+
assert_equal("#<Cairo::TextCluster: num_bytes=2, num_glyphs=3>",
|
12
|
+
cluster.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_accessor
|
16
|
+
only_cairo_version(1, 7, 2)
|
17
|
+
|
18
|
+
cluster = Cairo::TextCluster.new(5, 7)
|
19
|
+
assert_equal([5, 7], [cluster.num_bytes, cluster.num_glyphs])
|
20
|
+
cluster.num_bytes = 1
|
21
|
+
cluster.num_glyphs = 2
|
22
|
+
assert_equal([1, 2], [cluster.num_bytes, cluster.num_glyphs])
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_to_s
|
26
|
+
only_cairo_version(1, 7, 2)
|
27
|
+
|
28
|
+
cluster = Cairo::TextCluster.new(9, 1)
|
29
|
+
assert_equal("#<Cairo::TextCluster: num_bytes=9, num_glyphs=1>",
|
30
|
+
cluster.to_s)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'cairo'
|
2
|
+
|
3
|
+
class TextExtentsTest < Test::Unit::TestCase
|
4
|
+
include CairoTestUtils
|
5
|
+
|
6
|
+
def test_new
|
7
|
+
extents = Cairo::TextExtents.new
|
8
|
+
assert_equal([0.0, -1.0, 0.0, 1.0, 1.0, 0.0],
|
9
|
+
[extents.x_bearing, extents.y_bearing,
|
10
|
+
extents.width, extents.height,
|
11
|
+
extents.x_advance, extents.y_advance])
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_accessor
|
15
|
+
extents = Cairo::TextExtents.new
|
16
|
+
extents.x_bearing = 0.1
|
17
|
+
extents.y_bearing = 0.2
|
18
|
+
extents.width = 0.3
|
19
|
+
extents.height = 0.4
|
20
|
+
extents.x_advance = 0.5
|
21
|
+
extents.y_advance = 0.6
|
22
|
+
assert_equal([0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
|
23
|
+
[extents.x_bearing, extents.y_bearing,
|
24
|
+
extents.width, extents.height,
|
25
|
+
extents.x_advance, extents.y_advance])
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_to_s
|
29
|
+
extents = Cairo::TextExtents.new
|
30
|
+
extents.x_bearing = 0.1
|
31
|
+
extents.y_bearing = 0.2
|
32
|
+
extents.width = 0.3
|
33
|
+
extents.height = 0.4
|
34
|
+
extents.x_advance = 0.5
|
35
|
+
extents.y_advance = 0.6
|
36
|
+
assert_equal("#<Cairo::TextExtents: x_bearing=0.1, y_bearing=0.2, " +
|
37
|
+
"width=0.3, height=0.4, x_advance=0.5, y_advance=0.6>",
|
38
|
+
extents.to_s)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'cairo'
|
2
|
+
|
3
|
+
class TextToGlyphsDataTest < Test::Unit::TestCase
|
4
|
+
include CairoTestUtils
|
5
|
+
|
6
|
+
def test_new
|
7
|
+
only_cairo_version(1, 7, 6)
|
8
|
+
|
9
|
+
data = Cairo::UserFontFace::TextToGlyphsData.new(false, false, false)
|
10
|
+
assert_equal([false, false, false],
|
11
|
+
[data.need_glyphs?, data.need_clusters?,
|
12
|
+
data.need_cluster_flags?])
|
13
|
+
|
14
|
+
data = Cairo::UserFontFace::TextToGlyphsData.new(true, false, false)
|
15
|
+
assert_equal([true, false, false],
|
16
|
+
[data.need_glyphs?, data.need_clusters?,
|
17
|
+
data.need_cluster_flags?])
|
18
|
+
|
19
|
+
data = Cairo::UserFontFace::TextToGlyphsData.new(false, true, false)
|
20
|
+
assert_equal([false, true, false],
|
21
|
+
[data.need_glyphs?, data.need_clusters?,
|
22
|
+
data.need_cluster_flags?])
|
23
|
+
|
24
|
+
data = Cairo::UserFontFace::TextToGlyphsData.new(false, false, true)
|
25
|
+
assert_equal([false, false, true],
|
26
|
+
[data.need_glyphs?, data.need_clusters?,
|
27
|
+
data.need_cluster_flags?])
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_accessor
|
31
|
+
only_cairo_version(1, 7, 6)
|
32
|
+
|
33
|
+
data = Cairo::UserFontFace::TextToGlyphsData.new(true, true, true)
|
34
|
+
assert_equal([nil, nil, 0],
|
35
|
+
[data.glyphs, data.clusters, data.cluster_flags])
|
36
|
+
|
37
|
+
glyph = Cairo::Glyph.new(0, 5, 10)
|
38
|
+
data.glyphs = [glyph]
|
39
|
+
assert_equal([[glyph], nil, 0],
|
40
|
+
[data.glyphs, data.clusters, data.cluster_flags])
|
41
|
+
|
42
|
+
cluster = Cairo::TextCluster.new(0, 1)
|
43
|
+
data.clusters = [cluster]
|
44
|
+
assert_equal([[glyph], [cluster], 0],
|
45
|
+
[data.glyphs, data.clusters, data.cluster_flags])
|
46
|
+
|
47
|
+
data.cluster_flags = :backward
|
48
|
+
assert_equal([[glyph], [cluster], Cairo::TextClusterFlag::BACKWARD],
|
49
|
+
[data.glyphs, data.clusters, data.cluster_flags])
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,1836 @@
|
|
1
|
+
# module to create Makefile for extension modules
|
2
|
+
# invoke like: ruby -r mkmf extconf.rb
|
3
|
+
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'shellwords'
|
7
|
+
|
8
|
+
CONFIG = Config::MAKEFILE_CONFIG
|
9
|
+
ORIG_LIBPATH = ENV['LIB']
|
10
|
+
|
11
|
+
CXX_EXT = %w[cc cxx cpp]
|
12
|
+
if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os']
|
13
|
+
CXX_EXT.concat(%w[C])
|
14
|
+
end
|
15
|
+
SRC_EXT = %w[c m].concat(CXX_EXT)
|
16
|
+
$static = $config_h = nil
|
17
|
+
$default_static = $static
|
18
|
+
|
19
|
+
unless defined? $configure_args
|
20
|
+
$configure_args = {}
|
21
|
+
args = CONFIG["configure_args"]
|
22
|
+
if ENV["CONFIGURE_ARGS"]
|
23
|
+
args << " " << ENV["CONFIGURE_ARGS"]
|
24
|
+
end
|
25
|
+
for arg in Shellwords::shellwords(args)
|
26
|
+
arg, val = arg.split('=', 2)
|
27
|
+
next unless arg
|
28
|
+
arg.tr!('_', '-')
|
29
|
+
if arg.sub!(/^(?!--)/, '--')
|
30
|
+
val or next
|
31
|
+
arg.downcase!
|
32
|
+
end
|
33
|
+
next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
|
34
|
+
$configure_args[arg] = val || true
|
35
|
+
end
|
36
|
+
for arg in ARGV
|
37
|
+
arg, val = arg.split('=', 2)
|
38
|
+
next unless arg
|
39
|
+
arg.tr!('_', '-')
|
40
|
+
if arg.sub!(/^(?!--)/, '--')
|
41
|
+
val or next
|
42
|
+
arg.downcase!
|
43
|
+
end
|
44
|
+
$configure_args[arg] = val || true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
$libdir = CONFIG["libdir"]
|
49
|
+
$rubylibdir = CONFIG["rubylibdir"]
|
50
|
+
$archdir = CONFIG["archdir"]
|
51
|
+
$sitedir = CONFIG["sitedir"]
|
52
|
+
$sitelibdir = CONFIG["sitelibdir"]
|
53
|
+
$sitearchdir = CONFIG["sitearchdir"]
|
54
|
+
$vendordir = CONFIG["vendordir"]
|
55
|
+
$vendorlibdir = CONFIG["vendorlibdir"]
|
56
|
+
$vendorarchdir = CONFIG["vendorarchdir"]
|
57
|
+
|
58
|
+
$mswin = /mswin/ =~ RUBY_PLATFORM
|
59
|
+
$bccwin = /bccwin/ =~ RUBY_PLATFORM
|
60
|
+
$mingw = /mingw/ =~ RUBY_PLATFORM
|
61
|
+
$cygwin = /cygwin/ =~ RUBY_PLATFORM
|
62
|
+
$human = /human/ =~ RUBY_PLATFORM
|
63
|
+
$netbsd = /netbsd/ =~ RUBY_PLATFORM
|
64
|
+
$os2 = /os2/ =~ RUBY_PLATFORM
|
65
|
+
$beos = /beos/ =~ RUBY_PLATFORM
|
66
|
+
$solaris = /solaris/ =~ RUBY_PLATFORM
|
67
|
+
$dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
|
68
|
+
|
69
|
+
# :stopdoc:
|
70
|
+
|
71
|
+
def config_string(key, config = CONFIG)
|
72
|
+
s = config[key] and !s.empty? and block_given? ? yield(s) : s
|
73
|
+
end
|
74
|
+
|
75
|
+
def dir_re(dir)
|
76
|
+
Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
|
77
|
+
end
|
78
|
+
|
79
|
+
INSTALL_DIRS = [
|
80
|
+
[dir_re('commondir'), "$(RUBYCOMMONDIR)"],
|
81
|
+
[dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
|
82
|
+
[dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
|
83
|
+
[dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
|
84
|
+
[dir_re('archdir'), "$(RUBYARCHDIR)"],
|
85
|
+
[dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
|
86
|
+
[dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
|
87
|
+
[dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
|
88
|
+
[dir_re('bindir'), "$(BINDIR)"],
|
89
|
+
[dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
|
90
|
+
]
|
91
|
+
|
92
|
+
def install_dirs(target_prefix = nil)
|
93
|
+
if $extout
|
94
|
+
dirs = [
|
95
|
+
['BINDIR', '$(extout)/bin'],
|
96
|
+
['RUBYCOMMONDIR', '$(extout)/common'],
|
97
|
+
['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'],
|
98
|
+
['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
|
99
|
+
['extout', "#$extout"],
|
100
|
+
['extout_prefix', "#$extout_prefix"],
|
101
|
+
]
|
102
|
+
elsif $extmk
|
103
|
+
dirs = [
|
104
|
+
['BINDIR', '$(bindir)'],
|
105
|
+
['RUBYCOMMONDIR', '$(rubylibdir)'],
|
106
|
+
['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
|
107
|
+
['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
|
108
|
+
]
|
109
|
+
elsif $configure_args.has_key?('--vendor')
|
110
|
+
dirs = [
|
111
|
+
['BINDIR', '$(bindir)'],
|
112
|
+
['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
|
113
|
+
['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'],
|
114
|
+
['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'],
|
115
|
+
]
|
116
|
+
else
|
117
|
+
dirs = [
|
118
|
+
['BINDIR', '$(bindir)'],
|
119
|
+
['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
|
120
|
+
['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'],
|
121
|
+
['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'],
|
122
|
+
]
|
123
|
+
end
|
124
|
+
dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
|
125
|
+
dirs
|
126
|
+
end
|
127
|
+
|
128
|
+
def map_dir(dir, map = nil)
|
129
|
+
map ||= INSTALL_DIRS
|
130
|
+
map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
|
131
|
+
end
|
132
|
+
|
133
|
+
topdir = File.dirname(libdir = File.dirname(__FILE__))
|
134
|
+
extdir = File.expand_path("ext", topdir)
|
135
|
+
$extmk = File.expand_path($0)[0, extdir.size+1] == extdir+"/"
|
136
|
+
if not $extmk and File.exist?(($hdrdir = Config::CONFIG["archdir"]) + "/ruby.h")
|
137
|
+
$topdir = $hdrdir
|
138
|
+
elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir)) + "/ruby.h") and
|
139
|
+
File.exist?(($topdir ||= Config::CONFIG["topdir"]) + "/config.h")
|
140
|
+
else
|
141
|
+
abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
|
142
|
+
end
|
143
|
+
|
144
|
+
OUTFLAG = CONFIG['OUTFLAG']
|
145
|
+
CPPOUTFILE = CONFIG['CPPOUTFILE']
|
146
|
+
|
147
|
+
CONFTEST_C = "conftest.c"
|
148
|
+
|
149
|
+
class String
|
150
|
+
# Wraps a string in escaped quotes if it contains whitespace.
|
151
|
+
def quote
|
152
|
+
/\s/ =~ self ? "\"#{self}\"" : "#{self}"
|
153
|
+
end
|
154
|
+
|
155
|
+
# Generates a string used as cpp macro name.
|
156
|
+
def tr_cpp
|
157
|
+
strip.upcase.tr_s("^A-Z0-9_", "_")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
class Array
|
161
|
+
# Wraps all strings in escaped quotes if they contain whitespace.
|
162
|
+
def quote
|
163
|
+
map {|s| s.quote}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def rm_f(*files)
|
168
|
+
FileUtils.rm_f(Dir[files.join("\0")])
|
169
|
+
end
|
170
|
+
|
171
|
+
# Returns time stamp of the +target+ file if it exists and is newer
|
172
|
+
# than or equal to all of +times+.
|
173
|
+
def modified?(target, times)
|
174
|
+
(t = File.mtime(target)) rescue return nil
|
175
|
+
Array === times or times = [times]
|
176
|
+
t if times.all? {|n| n <= t}
|
177
|
+
end
|
178
|
+
|
179
|
+
def merge_libs(*libs)
|
180
|
+
libs.inject([]) do |x, y|
|
181
|
+
xy = x & y
|
182
|
+
xn = yn = 0
|
183
|
+
y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
|
184
|
+
y.each_with_index do |v, yi|
|
185
|
+
if xy.include?(v)
|
186
|
+
xi = [x.index(v), xn].max()
|
187
|
+
x[xi, 1] = y[yn..yi]
|
188
|
+
xn, yn = xi + (yi - yn + 1), yi + 1
|
189
|
+
end
|
190
|
+
end
|
191
|
+
x.concat(y[yn..-1] || [])
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# This is a custom logging module. It generates an mkmf.log file when you
|
196
|
+
# run your extconf.rb script. This can be useful for debugging unexpected
|
197
|
+
# failures.
|
198
|
+
#
|
199
|
+
# This module and its associated methods are meant for internal use only.
|
200
|
+
#
|
201
|
+
module Logging
|
202
|
+
@log = nil
|
203
|
+
@logfile = 'mkmf.log'
|
204
|
+
@orgerr = $stderr.dup
|
205
|
+
@orgout = $stdout.dup
|
206
|
+
@postpone = 0
|
207
|
+
@quiet = $extmk
|
208
|
+
|
209
|
+
def self::open
|
210
|
+
@log ||= File::open(@logfile, 'w')
|
211
|
+
@log.sync = true
|
212
|
+
$stderr.reopen(@log)
|
213
|
+
$stdout.reopen(@log)
|
214
|
+
yield
|
215
|
+
ensure
|
216
|
+
$stderr.reopen(@orgerr)
|
217
|
+
$stdout.reopen(@orgout)
|
218
|
+
end
|
219
|
+
|
220
|
+
def self::message(*s)
|
221
|
+
@log ||= File::open(@logfile, 'w')
|
222
|
+
@log.sync = true
|
223
|
+
@log.printf(*s)
|
224
|
+
end
|
225
|
+
|
226
|
+
def self::logfile file
|
227
|
+
@logfile = file
|
228
|
+
if @log and not @log.closed?
|
229
|
+
@log.flush
|
230
|
+
@log.close
|
231
|
+
@log = nil
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def self::postpone
|
236
|
+
tmplog = "mkmftmp#{@postpone += 1}.log"
|
237
|
+
open do
|
238
|
+
log, *save = @log, @logfile, @orgout, @orgerr
|
239
|
+
@log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
|
240
|
+
begin
|
241
|
+
log.print(open {yield})
|
242
|
+
@log.close
|
243
|
+
File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
|
244
|
+
ensure
|
245
|
+
@log, @logfile, @orgout, @orgerr = log, *save
|
246
|
+
@postpone -= 1
|
247
|
+
rm_f tmplog
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class << self
|
253
|
+
attr_accessor :quiet
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def xsystem command
|
258
|
+
varpat = /\$\((\w+)\)|\$\{(\w+)\}/
|
259
|
+
if varpat =~ command
|
260
|
+
vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
|
261
|
+
command = command.dup
|
262
|
+
nil while command.gsub!(varpat) {vars[$1||$2]}
|
263
|
+
end
|
264
|
+
Logging::open do
|
265
|
+
puts command.quote
|
266
|
+
system(command)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def xpopen command, *mode, &block
|
271
|
+
Logging::open do
|
272
|
+
case mode[0]
|
273
|
+
when nil, /^r/
|
274
|
+
puts "#{command} |"
|
275
|
+
else
|
276
|
+
puts "| #{command}"
|
277
|
+
end
|
278
|
+
IO.popen(command, *mode, &block)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def log_src(src)
|
283
|
+
src = src.split(/^/)
|
284
|
+
fmt = "%#{src.size.to_s.size}d: %s"
|
285
|
+
Logging::message <<"EOM"
|
286
|
+
checked program was:
|
287
|
+
/* begin */
|
288
|
+
EOM
|
289
|
+
src.each_with_index {|line, no| Logging::message fmt, no+1, line}
|
290
|
+
Logging::message <<"EOM"
|
291
|
+
/* end */
|
292
|
+
|
293
|
+
EOM
|
294
|
+
end
|
295
|
+
|
296
|
+
def create_tmpsrc(src)
|
297
|
+
src = yield(src) if block_given?
|
298
|
+
src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n")
|
299
|
+
open(CONFTEST_C, "wb") do |cfile|
|
300
|
+
cfile.print src
|
301
|
+
end
|
302
|
+
src
|
303
|
+
end
|
304
|
+
|
305
|
+
def try_do(src, command, &b)
|
306
|
+
src = create_tmpsrc(src, &b)
|
307
|
+
xsystem(command)
|
308
|
+
ensure
|
309
|
+
log_src(src)
|
310
|
+
end
|
311
|
+
|
312
|
+
def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
|
313
|
+
conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote,
|
314
|
+
'src' => CONFTEST_C,
|
315
|
+
'INCFLAGS' => $INCFLAGS,
|
316
|
+
'CPPFLAGS' => $CPPFLAGS,
|
317
|
+
'CFLAGS' => "#$CFLAGS",
|
318
|
+
'ARCH_FLAG' => "#$ARCH_FLAG",
|
319
|
+
'LDFLAGS' => "#$LDFLAGS #{ldflags}",
|
320
|
+
'LIBPATH' => libpathflag(libpath),
|
321
|
+
'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
|
322
|
+
'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS")
|
323
|
+
Config::expand(TRY_LINK.dup, conf)
|
324
|
+
end
|
325
|
+
|
326
|
+
def cc_command(opt="")
|
327
|
+
conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
|
328
|
+
Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
|
329
|
+
conf)
|
330
|
+
end
|
331
|
+
|
332
|
+
def cpp_command(outfile, opt="")
|
333
|
+
conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
|
334
|
+
Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
|
335
|
+
conf)
|
336
|
+
end
|
337
|
+
|
338
|
+
def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
|
339
|
+
libpath.map{|x|
|
340
|
+
case x
|
341
|
+
when "$(topdir)", /\A\./
|
342
|
+
LIBPATHFLAG
|
343
|
+
else
|
344
|
+
LIBPATHFLAG+RPATHFLAG
|
345
|
+
end % x.quote
|
346
|
+
}.join
|
347
|
+
end
|
348
|
+
|
349
|
+
def try_link0(src, opt="", &b)
|
350
|
+
try_do(src, link_command("", opt), &b)
|
351
|
+
end
|
352
|
+
|
353
|
+
def try_link(src, opt="", &b)
|
354
|
+
try_link0(src, opt, &b)
|
355
|
+
ensure
|
356
|
+
rm_f "conftest*", "c0x32*"
|
357
|
+
end
|
358
|
+
|
359
|
+
def try_compile(src, opt="", &b)
|
360
|
+
try_do(src, cc_command(opt), &b)
|
361
|
+
ensure
|
362
|
+
rm_f "conftest*"
|
363
|
+
end
|
364
|
+
|
365
|
+
def try_cpp(src, opt="", &b)
|
366
|
+
try_do(src, cpp_command(CPPOUTFILE, opt), &b)
|
367
|
+
ensure
|
368
|
+
rm_f "conftest*"
|
369
|
+
end
|
370
|
+
|
371
|
+
def cpp_include(header)
|
372
|
+
if header
|
373
|
+
header = [header] unless header.kind_of? Array
|
374
|
+
header.map {|h| "#include <#{h}>\n"}.join
|
375
|
+
else
|
376
|
+
""
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def with_cppflags(flags)
|
381
|
+
cppflags = $CPPFLAGS
|
382
|
+
$CPPFLAGS = flags
|
383
|
+
ret = yield
|
384
|
+
ensure
|
385
|
+
$CPPFLAGS = cppflags unless ret
|
386
|
+
end
|
387
|
+
|
388
|
+
def with_cflags(flags)
|
389
|
+
cflags = $CFLAGS
|
390
|
+
$CFLAGS = flags
|
391
|
+
ret = yield
|
392
|
+
ensure
|
393
|
+
$CFLAGS = cflags unless ret
|
394
|
+
end
|
395
|
+
|
396
|
+
def with_ldflags(flags)
|
397
|
+
ldflags = $LDFLAGS
|
398
|
+
$LDFLAGS = flags
|
399
|
+
ret = yield
|
400
|
+
ensure
|
401
|
+
$LDFLAGS = ldflags unless ret
|
402
|
+
end
|
403
|
+
|
404
|
+
def try_static_assert(expr, headers = nil, opt = "", &b)
|
405
|
+
headers = cpp_include(headers)
|
406
|
+
try_compile(<<SRC, opt, &b)
|
407
|
+
#{COMMON_HEADERS}
|
408
|
+
#{headers}
|
409
|
+
/*top*/
|
410
|
+
int conftest_const[(#{expr}) ? 1 : -1];
|
411
|
+
SRC
|
412
|
+
end
|
413
|
+
|
414
|
+
def try_constant(const, headers = nil, opt = "", &b)
|
415
|
+
includes = cpp_include(headers)
|
416
|
+
if CROSS_COMPILING
|
417
|
+
if try_static_assert("#{const} > 0", headers, opt)
|
418
|
+
# positive constant
|
419
|
+
elsif try_static_assert("#{const} < 0", headers, opt)
|
420
|
+
neg = true
|
421
|
+
const = "-(#{const})"
|
422
|
+
elsif try_static_assert("#{const} == 0", headers, opt)
|
423
|
+
return 0
|
424
|
+
else
|
425
|
+
# not a constant
|
426
|
+
return nil
|
427
|
+
end
|
428
|
+
upper = 1
|
429
|
+
lower = 0
|
430
|
+
until try_static_assert("#{const} <= #{upper}", headers, opt)
|
431
|
+
lower = upper
|
432
|
+
upper <<= 1
|
433
|
+
end
|
434
|
+
return nil unless lower
|
435
|
+
while upper > lower + 1
|
436
|
+
mid = (upper + lower) / 2
|
437
|
+
if try_static_assert("#{const} > #{mid}", headers, opt)
|
438
|
+
lower = mid
|
439
|
+
else
|
440
|
+
upper = mid
|
441
|
+
end
|
442
|
+
end
|
443
|
+
upper = -upper if neg
|
444
|
+
return upper
|
445
|
+
else
|
446
|
+
src = %{#{COMMON_HEADERS}
|
447
|
+
#{includes}
|
448
|
+
#include <stdio.h>
|
449
|
+
/*top*/
|
450
|
+
int conftest_const = (int)(#{const});
|
451
|
+
int main() {printf("%d\\n", conftest_const); return 0;}
|
452
|
+
}
|
453
|
+
if try_link0(src, opt, &b)
|
454
|
+
xpopen("./conftest") do |f|
|
455
|
+
return Integer(f.gets)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
nil
|
460
|
+
end
|
461
|
+
|
462
|
+
def try_func(func, libs, headers = nil, &b)
|
463
|
+
headers = cpp_include(headers)
|
464
|
+
try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b)
|
465
|
+
#{COMMON_HEADERS}
|
466
|
+
#{headers}
|
467
|
+
/*top*/
|
468
|
+
int main() { return 0; }
|
469
|
+
int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
|
470
|
+
SRC
|
471
|
+
#{headers}
|
472
|
+
/*top*/
|
473
|
+
int main() { return 0; }
|
474
|
+
int t() { #{func}(); return 0; }
|
475
|
+
SRC
|
476
|
+
end
|
477
|
+
|
478
|
+
def try_var(var, headers = nil, &b)
|
479
|
+
headers = cpp_include(headers)
|
480
|
+
try_compile(<<"SRC", &b)
|
481
|
+
#{COMMON_HEADERS}
|
482
|
+
#{headers}
|
483
|
+
/*top*/
|
484
|
+
int main() { return 0; }
|
485
|
+
int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
|
486
|
+
SRC
|
487
|
+
end
|
488
|
+
|
489
|
+
def egrep_cpp(pat, src, opt = "", &b)
|
490
|
+
src = create_tmpsrc(src, &b)
|
491
|
+
xpopen(cpp_command('', opt)) do |f|
|
492
|
+
if Regexp === pat
|
493
|
+
puts(" ruby -ne 'print if #{pat.inspect}'")
|
494
|
+
f.grep(pat) {|l|
|
495
|
+
puts "#{f.lineno}: #{l}"
|
496
|
+
return true
|
497
|
+
}
|
498
|
+
false
|
499
|
+
else
|
500
|
+
puts(" egrep '#{pat}'")
|
501
|
+
begin
|
502
|
+
stdin = $stdin.dup
|
503
|
+
$stdin.reopen(f)
|
504
|
+
system("egrep", pat)
|
505
|
+
ensure
|
506
|
+
$stdin.reopen(stdin)
|
507
|
+
end
|
508
|
+
end
|
509
|
+
end
|
510
|
+
ensure
|
511
|
+
rm_f "conftest*"
|
512
|
+
log_src(src)
|
513
|
+
end
|
514
|
+
|
515
|
+
# This is used internally by the have_macro? method.
|
516
|
+
def macro_defined?(macro, src, opt = "", &b)
|
517
|
+
src = src.sub(/[^\n]\z/, "\\&\n")
|
518
|
+
try_compile(src + <<"SRC", opt, &b)
|
519
|
+
/*top*/
|
520
|
+
#ifndef #{macro}
|
521
|
+
# error
|
522
|
+
>>>>>> #{macro} undefined <<<<<<
|
523
|
+
#endif
|
524
|
+
SRC
|
525
|
+
end
|
526
|
+
|
527
|
+
def try_run(src, opt = "", &b)
|
528
|
+
if try_link0(src, opt, &b)
|
529
|
+
xsystem("./conftest")
|
530
|
+
else
|
531
|
+
nil
|
532
|
+
end
|
533
|
+
ensure
|
534
|
+
rm_f "conftest*"
|
535
|
+
end
|
536
|
+
|
537
|
+
def install_files(mfile, ifiles, map = nil, srcprefix = nil)
|
538
|
+
ifiles or return
|
539
|
+
ifiles.empty? and return
|
540
|
+
srcprefix ||= '$(srcdir)'
|
541
|
+
Config::expand(srcdir = srcprefix.dup)
|
542
|
+
dirs = []
|
543
|
+
path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
|
544
|
+
ifiles.each do |files, dir, prefix|
|
545
|
+
dir = map_dir(dir, map)
|
546
|
+
prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
|
547
|
+
if /\A\.\// =~ files
|
548
|
+
# install files which are in current working directory.
|
549
|
+
files = files[2..-1]
|
550
|
+
len = nil
|
551
|
+
else
|
552
|
+
# install files which are under the $(srcdir).
|
553
|
+
files = File.join(srcdir, files)
|
554
|
+
len = srcdir.size
|
555
|
+
end
|
556
|
+
f = nil
|
557
|
+
Dir.glob(files) do |f|
|
558
|
+
f[0..len] = "" if len
|
559
|
+
case File.basename(f)
|
560
|
+
when *$NONINSTALLFILES
|
561
|
+
next
|
562
|
+
end
|
563
|
+
d = File.dirname(f)
|
564
|
+
d.sub!(prefix, "") if prefix
|
565
|
+
d = (d.empty? || d == ".") ? dir : File.join(dir, d)
|
566
|
+
f = File.join(srcprefix, f) if len
|
567
|
+
path[d] << f
|
568
|
+
end
|
569
|
+
unless len or f
|
570
|
+
d = File.dirname(files)
|
571
|
+
d.sub!(prefix, "") if prefix
|
572
|
+
d = (d.empty? || d == ".") ? dir : File.join(dir, d)
|
573
|
+
path[d] << files
|
574
|
+
end
|
575
|
+
end
|
576
|
+
dirs
|
577
|
+
end
|
578
|
+
|
579
|
+
def install_rb(mfile, dest, srcdir = nil)
|
580
|
+
install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
|
581
|
+
end
|
582
|
+
|
583
|
+
def append_library(libs, lib) # :no-doc:
|
584
|
+
format(LIBARG, lib) + " " + libs
|
585
|
+
end
|
586
|
+
|
587
|
+
def message(*s)
|
588
|
+
unless Logging.quiet and not $VERBOSE
|
589
|
+
printf(*s)
|
590
|
+
$stdout.flush
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
594
|
+
# This emits a string to stdout that allows users to see the results of the
|
595
|
+
# various have* and find* methods as they are tested.
|
596
|
+
#
|
597
|
+
# Internal use only.
|
598
|
+
#
|
599
|
+
def checking_for(m, fmt = nil)
|
600
|
+
f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim
|
601
|
+
m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
|
602
|
+
message "%s", m
|
603
|
+
a = r = nil
|
604
|
+
Logging::postpone do
|
605
|
+
r = yield
|
606
|
+
a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
|
607
|
+
"#{f}#{m}-------------------- #{a}\n"
|
608
|
+
end
|
609
|
+
message(a)
|
610
|
+
Logging::message "--------------------\n\n"
|
611
|
+
r
|
612
|
+
end
|
613
|
+
|
614
|
+
def checking_message(target, place = nil, opt = nil)
|
615
|
+
[["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
|
616
|
+
if noun
|
617
|
+
[[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
|
618
|
+
if noun.respond_to?(meth)
|
619
|
+
break noun = noun.send(meth, *args)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
msg << " #{pre} #{noun}" unless noun.empty?
|
623
|
+
end
|
624
|
+
msg
|
625
|
+
end
|
626
|
+
end
|
627
|
+
|
628
|
+
# :startdoc:
|
629
|
+
|
630
|
+
# Returns whether or not +macro+ is defined either in the common header
|
631
|
+
# files or within any +headers+ you provide.
|
632
|
+
#
|
633
|
+
# Any options you pass to +opt+ are passed along to the compiler.
|
634
|
+
#
|
635
|
+
def have_macro(macro, headers = nil, opt = "", &b)
|
636
|
+
checking_for checking_message(macro, headers, opt) do
|
637
|
+
macro_defined?(macro, cpp_include(headers), opt, &b)
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
# Returns whether or not the given entry point +func+ can be found within
|
642
|
+
# +lib+. If +func+ is nil, the 'main()' entry point is used by default.
|
643
|
+
# If found, it adds the library to list of libraries to be used when linking
|
644
|
+
# your extension.
|
645
|
+
#
|
646
|
+
# If +headers+ are provided, it will include those header files as the
|
647
|
+
# header files it looks in when searching for +func+.
|
648
|
+
#
|
649
|
+
# The real name of the library to be linked can be altered by
|
650
|
+
# '--with-FOOlib' configuration option.
|
651
|
+
#
|
652
|
+
def have_library(lib, func = nil, headers = nil, &b)
|
653
|
+
func = "main" if !func or func.empty?
|
654
|
+
lib = with_config(lib+'lib', lib)
|
655
|
+
checking_for checking_message("#{func}()", LIBARG%lib) do
|
656
|
+
if COMMON_LIBS.include?(lib)
|
657
|
+
true
|
658
|
+
else
|
659
|
+
libs = append_library($libs, lib)
|
660
|
+
if try_func(func, libs, headers, &b)
|
661
|
+
$libs = libs
|
662
|
+
true
|
663
|
+
else
|
664
|
+
false
|
665
|
+
end
|
666
|
+
end
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
# Returns whether or not the entry point +func+ can be found within the library
|
671
|
+
# +lib+ in one of the +paths+ specified, where +paths+ is an array of strings.
|
672
|
+
# If +func+ is nil , then the main() function is used as the entry point.
|
673
|
+
#
|
674
|
+
# If +lib+ is found, then the path it was found on is added to the list of
|
675
|
+
# library paths searched and linked against.
|
676
|
+
#
|
677
|
+
def find_library(lib, func, *paths, &b)
|
678
|
+
func = "main" if !func or func.empty?
|
679
|
+
lib = with_config(lib+'lib', lib)
|
680
|
+
paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
|
681
|
+
checking_for "#{func}() in #{LIBARG%lib}" do
|
682
|
+
libpath = $LIBPATH
|
683
|
+
libs = append_library($libs, lib)
|
684
|
+
begin
|
685
|
+
until r = try_func(func, libs, &b) or paths.empty?
|
686
|
+
$LIBPATH = libpath | [paths.shift]
|
687
|
+
end
|
688
|
+
if r
|
689
|
+
$libs = libs
|
690
|
+
libpath = nil
|
691
|
+
end
|
692
|
+
ensure
|
693
|
+
$LIBPATH = libpath if libpath
|
694
|
+
end
|
695
|
+
r
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
# Returns whether or not the function +func+ can be found in the common
|
700
|
+
# header files, or within any +headers+ that you provide. If found, a
|
701
|
+
# macro is passed as a preprocessor constant to the compiler using the
|
702
|
+
# function name, in uppercase, prepended with 'HAVE_'.
|
703
|
+
#
|
704
|
+
# For example, if have_func('foo') returned true, then the HAVE_FOO
|
705
|
+
# preprocessor macro would be passed to the compiler.
|
706
|
+
#
|
707
|
+
def have_func(func, headers = nil, &b)
|
708
|
+
checking_for checking_message("#{func}()", headers) do
|
709
|
+
if try_func(func, $libs, headers, &b)
|
710
|
+
$defs.push(format("-DHAVE_%s", func.tr_cpp))
|
711
|
+
true
|
712
|
+
else
|
713
|
+
false
|
714
|
+
end
|
715
|
+
end
|
716
|
+
end
|
717
|
+
|
718
|
+
# Returns whether or not the variable +var+ can be found in the common
|
719
|
+
# header files, or within any +headers+ that you provide. If found, a
|
720
|
+
# macro is passed as a preprocessor constant to the compiler using the
|
721
|
+
# variable name, in uppercase, prepended with 'HAVE_'.
|
722
|
+
#
|
723
|
+
# For example, if have_var('foo') returned true, then the HAVE_FOO
|
724
|
+
# preprocessor macro would be passed to the compiler.
|
725
|
+
#
|
726
|
+
def have_var(var, headers = nil, &b)
|
727
|
+
checking_for checking_message(var, headers) do
|
728
|
+
if try_var(var, headers, &b)
|
729
|
+
$defs.push(format("-DHAVE_%s", var.tr_cpp))
|
730
|
+
true
|
731
|
+
else
|
732
|
+
false
|
733
|
+
end
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
# Returns whether or not the given +header+ file can be found on your system.
|
738
|
+
# If found, a macro is passed as a preprocessor constant to the compiler using
|
739
|
+
# the header file name, in uppercase, prepended with 'HAVE_'.
|
740
|
+
#
|
741
|
+
# For example, if have_header('foo.h') returned true, then the HAVE_FOO_H
|
742
|
+
# preprocessor macro would be passed to the compiler.
|
743
|
+
#
|
744
|
+
def have_header(header, &b)
|
745
|
+
checking_for header do
|
746
|
+
if try_cpp(cpp_include(header), &b)
|
747
|
+
$defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
|
748
|
+
true
|
749
|
+
else
|
750
|
+
false
|
751
|
+
end
|
752
|
+
end
|
753
|
+
end
|
754
|
+
|
755
|
+
# Instructs mkmf to search for the given +header+ in any of the +paths+
|
756
|
+
# provided, and returns whether or not it was found in those paths.
|
757
|
+
#
|
758
|
+
# If the header is found then the path it was found on is added to the list
|
759
|
+
# of included directories that are sent to the compiler (via the -I switch).
|
760
|
+
#
|
761
|
+
def find_header(header, *paths)
|
762
|
+
message = checking_message(header, paths)
|
763
|
+
header = cpp_include(header)
|
764
|
+
checking_for message do
|
765
|
+
if try_cpp(header)
|
766
|
+
true
|
767
|
+
else
|
768
|
+
found = false
|
769
|
+
paths.each do |dir|
|
770
|
+
opt = "-I#{dir}".quote
|
771
|
+
if try_cpp(header, opt)
|
772
|
+
$INCFLAGS << " " << opt
|
773
|
+
found = true
|
774
|
+
break
|
775
|
+
end
|
776
|
+
end
|
777
|
+
found
|
778
|
+
end
|
779
|
+
end
|
780
|
+
end
|
781
|
+
|
782
|
+
# Returns whether or not the struct of type +type+ contains +member+. If
|
783
|
+
# it does not, or the struct type can't be found, then false is returned. You
|
784
|
+
# may optionally specify additional +headers+ in which to look for the struct
|
785
|
+
# (in addition to the common header files).
|
786
|
+
#
|
787
|
+
# If found, a macro is passed as a preprocessor constant to the compiler using
|
788
|
+
# the member name, in uppercase, prepended with 'HAVE_ST_'.
|
789
|
+
#
|
790
|
+
# For example, if have_struct_member('struct foo', 'bar') returned true, then the
|
791
|
+
# HAVE_ST_BAR preprocessor macro would be passed to the compiler.
|
792
|
+
#
|
793
|
+
def have_struct_member(type, member, headers = nil, &b)
|
794
|
+
checking_for checking_message("#{type}.#{member}", headers) do
|
795
|
+
if try_compile(<<"SRC", &b)
|
796
|
+
#{COMMON_HEADERS}
|
797
|
+
#{cpp_include(headers)}
|
798
|
+
/*top*/
|
799
|
+
int main() { return 0; }
|
800
|
+
int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
|
801
|
+
SRC
|
802
|
+
$defs.push(format("-DHAVE_ST_%s", member.tr_cpp))
|
803
|
+
true
|
804
|
+
else
|
805
|
+
false
|
806
|
+
end
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
def try_type(type, headers = nil, opt = "", &b)
|
811
|
+
if try_compile(<<"SRC", opt, &b)
|
812
|
+
#{COMMON_HEADERS}
|
813
|
+
#{cpp_include(headers)}
|
814
|
+
/*top*/
|
815
|
+
typedef #{type} conftest_type;
|
816
|
+
int conftestval[sizeof(conftest_type)?1:-1];
|
817
|
+
SRC
|
818
|
+
$defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
|
819
|
+
true
|
820
|
+
else
|
821
|
+
false
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
# Returns whether or not the static type +type+ is defined. You may
|
826
|
+
# optionally pass additional +headers+ to check against in addition to the
|
827
|
+
# common header files.
|
828
|
+
#
|
829
|
+
# You may also pass additional flags to +opt+ which are then passed along to
|
830
|
+
# the compiler.
|
831
|
+
#
|
832
|
+
# If found, a macro is passed as a preprocessor constant to the compiler using
|
833
|
+
# the type name, in uppercase, prepended with 'HAVE_TYPE_'.
|
834
|
+
#
|
835
|
+
# For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO
|
836
|
+
# preprocessor macro would be passed to the compiler.
|
837
|
+
#
|
838
|
+
def have_type(type, headers = nil, opt = "", &b)
|
839
|
+
checking_for checking_message(type, headers, opt) do
|
840
|
+
try_type(type, headers, opt, &b)
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
# Returns where the static type +type+ is defined.
|
845
|
+
#
|
846
|
+
# You may also pass additional flags to +opt+ which are then passed along to
|
847
|
+
# the compiler.
|
848
|
+
#
|
849
|
+
# See also +have_type+.
|
850
|
+
#
|
851
|
+
def find_type(type, opt, *headers, &b)
|
852
|
+
opt ||= ""
|
853
|
+
fmt = "not found"
|
854
|
+
def fmt.%(x)
|
855
|
+
x ? x.respond_to?(:join) ? x.join(",") : x : self
|
856
|
+
end
|
857
|
+
checking_for checking_message(type, nil, opt), fmt do
|
858
|
+
headers.find do |h|
|
859
|
+
try_type(type, h, opt, &b)
|
860
|
+
end
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
def try_const(const, headers = nil, opt = "", &b)
|
865
|
+
const, type = *const
|
866
|
+
if try_compile(<<"SRC", opt, &b)
|
867
|
+
#{COMMON_HEADERS}
|
868
|
+
#{cpp_include(headers)}
|
869
|
+
/*top*/
|
870
|
+
typedef #{type || 'int'} conftest_type;
|
871
|
+
conftest_type conftestval = #{type ? '' : '(int)'}#{const};
|
872
|
+
SRC
|
873
|
+
$defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
|
874
|
+
true
|
875
|
+
else
|
876
|
+
false
|
877
|
+
end
|
878
|
+
end
|
879
|
+
|
880
|
+
# Returns whether or not the constant +const+ is defined. You may
|
881
|
+
# optionally pass the +type+ of +const+ as <code>[const, type]</code>,
|
882
|
+
# like as:
|
883
|
+
#
|
884
|
+
# have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
|
885
|
+
#
|
886
|
+
# You may also pass additional +headers+ to check against in addition
|
887
|
+
# to the common header files, and additional flags to +opt+ which are
|
888
|
+
# then passed along to the compiler.
|
889
|
+
#
|
890
|
+
# If found, a macro is passed as a preprocessor constant to the compiler using
|
891
|
+
# the type name, in uppercase, prepended with 'HAVE_CONST_'.
|
892
|
+
#
|
893
|
+
# For example, if have_const('foo') returned true, then the HAVE_CONST_FOO
|
894
|
+
# preprocessor macro would be passed to the compiler.
|
895
|
+
#
|
896
|
+
def have_const(const, headers = nil, opt = "", &b)
|
897
|
+
checking_for checking_message([*const].compact.join(' '), headers, opt) do
|
898
|
+
try_const(const, headers, opt, &b)
|
899
|
+
end
|
900
|
+
end
|
901
|
+
|
902
|
+
# Returns the size of the given +type+. You may optionally specify additional
|
903
|
+
# +headers+ to search in for the +type+.
|
904
|
+
#
|
905
|
+
# If found, a macro is passed as a preprocessor constant to the compiler using
|
906
|
+
# the type name, in uppercase, prepended with 'SIZEOF_', followed by the type
|
907
|
+
# name, followed by '=X' where 'X' is the actual size.
|
908
|
+
#
|
909
|
+
# For example, if check_sizeof('mystruct') returned 12, then the
|
910
|
+
# SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
|
911
|
+
#
|
912
|
+
def check_sizeof(type, headers = nil, &b)
|
913
|
+
expr = "sizeof(#{type})"
|
914
|
+
fmt = "%d"
|
915
|
+
def fmt.%(x)
|
916
|
+
x ? super : "failed"
|
917
|
+
end
|
918
|
+
checking_for checking_message("size of #{type}", headers), fmt do
|
919
|
+
if size = try_constant(expr, headers, &b)
|
920
|
+
$defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
|
921
|
+
size
|
922
|
+
end
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
# :stopdoc:
|
927
|
+
|
928
|
+
# Used internally by the what_type? method to determine if +type+ is a scalar
|
929
|
+
# pointer.
|
930
|
+
def scalar_ptr_type?(type, member = nil, headers = nil, &b)
|
931
|
+
try_compile(<<"SRC", &b) # pointer
|
932
|
+
#{COMMON_HEADERS}
|
933
|
+
#{cpp_include(headers)}
|
934
|
+
/*top*/
|
935
|
+
volatile #{type} conftestval;
|
936
|
+
int main() { return 0; }
|
937
|
+
int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
|
938
|
+
SRC
|
939
|
+
end
|
940
|
+
|
941
|
+
# Used internally by the what_type? method to determine if +type+ is a scalar
|
942
|
+
# pointer.
|
943
|
+
def scalar_type?(type, member = nil, headers = nil, &b)
|
944
|
+
try_compile(<<"SRC", &b) # pointer
|
945
|
+
#{COMMON_HEADERS}
|
946
|
+
#{cpp_include(headers)}
|
947
|
+
/*top*/
|
948
|
+
volatile #{type} conftestval;
|
949
|
+
int main() { return 0; }
|
950
|
+
int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
|
951
|
+
SRC
|
952
|
+
end
|
953
|
+
|
954
|
+
def what_type?(type, member = nil, headers = nil, &b)
|
955
|
+
m = "#{type}"
|
956
|
+
name = type
|
957
|
+
if member
|
958
|
+
m << "." << member
|
959
|
+
name = "(((#{type} *)0)->#{member})"
|
960
|
+
end
|
961
|
+
fmt = "seems %s"
|
962
|
+
def fmt.%(x)
|
963
|
+
x ? super : "unknown"
|
964
|
+
end
|
965
|
+
checking_for checking_message(m, headers), fmt do
|
966
|
+
if scalar_ptr_type?(type, member, headers, &b)
|
967
|
+
if try_static_assert("sizeof(*#{name}) == 1", headers)
|
968
|
+
"string"
|
969
|
+
end
|
970
|
+
elsif scalar_type?(type, member, headers, &b)
|
971
|
+
if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
|
972
|
+
"long long"
|
973
|
+
elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
|
974
|
+
"long"
|
975
|
+
elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
|
976
|
+
"int"
|
977
|
+
elsif try_static_assert("sizeof(#{name}) > 1", headers)
|
978
|
+
"short"
|
979
|
+
else
|
980
|
+
"char"
|
981
|
+
end
|
982
|
+
end
|
983
|
+
end
|
984
|
+
end
|
985
|
+
|
986
|
+
# This method is used internally by the find_executable method.
|
987
|
+
#
|
988
|
+
# Internal use only.
|
989
|
+
#
|
990
|
+
def find_executable0(bin, path = nil)
|
991
|
+
ext = config_string('EXEEXT')
|
992
|
+
if File.expand_path(bin) == bin
|
993
|
+
return bin if File.executable?(bin)
|
994
|
+
ext and File.executable?(file = bin + ext) and return file
|
995
|
+
return nil
|
996
|
+
end
|
997
|
+
if path ||= ENV['PATH']
|
998
|
+
path = path.split(File::PATH_SEPARATOR)
|
999
|
+
else
|
1000
|
+
path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
|
1001
|
+
end
|
1002
|
+
file = nil
|
1003
|
+
path.each do |dir|
|
1004
|
+
return file if File.executable?(file = File.join(dir, bin))
|
1005
|
+
return file if ext and File.executable?(file << ext)
|
1006
|
+
end
|
1007
|
+
nil
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
# :startdoc:
|
1011
|
+
|
1012
|
+
# Searches for the executable +bin+ on +path+. The default path is your
|
1013
|
+
# PATH environment variable. If that isn't defined, it will resort to
|
1014
|
+
# searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
|
1015
|
+
#
|
1016
|
+
# If found, it will return the full path, including the executable name,
|
1017
|
+
# of where it was found.
|
1018
|
+
#
|
1019
|
+
# Note that this method does not actually affect the generated Makefile.
|
1020
|
+
#
|
1021
|
+
def find_executable(bin, path = nil)
|
1022
|
+
checking_for checking_message(bin, path) do
|
1023
|
+
find_executable0(bin, path)
|
1024
|
+
end
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
# :stopdoc:
|
1028
|
+
|
1029
|
+
def arg_config(config, *defaults, &block)
|
1030
|
+
$arg_config << [config, *defaults]
|
1031
|
+
defaults << nil if !block and defaults.empty?
|
1032
|
+
$configure_args.fetch(config.tr('_', '-'), *defaults, &block)
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
# :startdoc:
|
1036
|
+
|
1037
|
+
# Tests for the presence of a --with-<tt>config</tt> or --without-<tt>config</tt>
|
1038
|
+
# option. Returns true if the with option is given, false if the without
|
1039
|
+
# option is given, and the default value otherwise.
|
1040
|
+
#
|
1041
|
+
# This can be useful for adding custom definitions, such as debug information.
|
1042
|
+
#
|
1043
|
+
# Example:
|
1044
|
+
#
|
1045
|
+
# if with_config("debug")
|
1046
|
+
# $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
|
1047
|
+
# end
|
1048
|
+
#
|
1049
|
+
def with_config(config, *defaults)
|
1050
|
+
config = config.sub(/^--with[-_]/, '')
|
1051
|
+
val = arg_config("--with-"+config) do
|
1052
|
+
if arg_config("--without-"+config)
|
1053
|
+
false
|
1054
|
+
elsif block_given?
|
1055
|
+
yield(config, *defaults)
|
1056
|
+
else
|
1057
|
+
break *defaults
|
1058
|
+
end
|
1059
|
+
end
|
1060
|
+
case val
|
1061
|
+
when "yes"
|
1062
|
+
true
|
1063
|
+
when "no"
|
1064
|
+
false
|
1065
|
+
else
|
1066
|
+
val
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
# Tests for the presence of an --enable-<tt>config</tt> or
|
1071
|
+
# --disable-<tt>config</tt> option. Returns true if the enable option is given,
|
1072
|
+
# false if the disable option is given, and the default value otherwise.
|
1073
|
+
#
|
1074
|
+
# This can be useful for adding custom definitions, such as debug information.
|
1075
|
+
#
|
1076
|
+
# Example:
|
1077
|
+
#
|
1078
|
+
# if enable_config("debug")
|
1079
|
+
# $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
|
1080
|
+
# end
|
1081
|
+
#
|
1082
|
+
def enable_config(config, *defaults)
|
1083
|
+
if arg_config("--enable-"+config)
|
1084
|
+
true
|
1085
|
+
elsif arg_config("--disable-"+config)
|
1086
|
+
false
|
1087
|
+
elsif block_given?
|
1088
|
+
yield(config, *defaults)
|
1089
|
+
else
|
1090
|
+
return *defaults
|
1091
|
+
end
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
# Generates a header file consisting of the various macro definitions generated
|
1095
|
+
# by other methods such as have_func and have_header. These are then wrapped in
|
1096
|
+
# a custom #ifndef based on the +header+ file name, which defaults to
|
1097
|
+
# 'extconf.h'.
|
1098
|
+
#
|
1099
|
+
# For example:
|
1100
|
+
#
|
1101
|
+
# # extconf.rb
|
1102
|
+
# require 'mkmf'
|
1103
|
+
# have_func('realpath')
|
1104
|
+
# have_header('sys/utime.h')
|
1105
|
+
# create_header
|
1106
|
+
# create_makefile('foo')
|
1107
|
+
#
|
1108
|
+
# The above script would generate the following extconf.h file:
|
1109
|
+
#
|
1110
|
+
# #ifndef EXTCONF_H
|
1111
|
+
# #define EXTCONF_H
|
1112
|
+
# #define HAVE_REALPATH 1
|
1113
|
+
# #define HAVE_SYS_UTIME_H 1
|
1114
|
+
# #endif
|
1115
|
+
#
|
1116
|
+
# Given that the create_header method generates a file based on definitions
|
1117
|
+
# set earlier in your extconf.rb file, you will probably want to make this
|
1118
|
+
# one of the last methods you call in your script.
|
1119
|
+
#
|
1120
|
+
def create_header(header = "extconf.h")
|
1121
|
+
message "creating %s\n", header
|
1122
|
+
sym = header.tr("a-z./\055", "A-Z___")
|
1123
|
+
hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
|
1124
|
+
for line in $defs
|
1125
|
+
case line
|
1126
|
+
when /^-D([^=]+)(?:=(.*))?/
|
1127
|
+
hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
|
1128
|
+
when /^-U(.*)/
|
1129
|
+
hdr << "#undef #$1\n"
|
1130
|
+
end
|
1131
|
+
end
|
1132
|
+
hdr << "#endif\n"
|
1133
|
+
hdr = hdr.join
|
1134
|
+
unless (IO.read(header) == hdr rescue false)
|
1135
|
+
open(header, "w") do |hfile|
|
1136
|
+
hfile.write(hdr)
|
1137
|
+
end
|
1138
|
+
end
|
1139
|
+
$extconf_h = header
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
# Sets a +target+ name that the user can then use to configure various 'with'
|
1143
|
+
# options with on the command line by using that name. For example, if the
|
1144
|
+
# target is set to "foo", then the user could use the --with-foo-dir command
|
1145
|
+
# line option.
|
1146
|
+
#
|
1147
|
+
# You may pass along additional 'include' or 'lib' defaults via the +idefault+
|
1148
|
+
# and +ldefault+ parameters, respectively.
|
1149
|
+
#
|
1150
|
+
# Note that dir_config only adds to the list of places to search for libraries
|
1151
|
+
# and include files. It does not link the libraries into your application.
|
1152
|
+
#
|
1153
|
+
def dir_config(target, idefault=nil, ldefault=nil)
|
1154
|
+
if dir = with_config(target + "-dir", (idefault unless ldefault))
|
1155
|
+
defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
|
1156
|
+
idefault = ldefault = nil
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
idir = with_config(target + "-include", idefault)
|
1160
|
+
$arg_config.last[1] ||= "${#{target}-dir}/include"
|
1161
|
+
ldir = with_config(target + "-lib", ldefault)
|
1162
|
+
$arg_config.last[1] ||= "${#{target}-dir}/lib"
|
1163
|
+
|
1164
|
+
idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
|
1165
|
+
if defaults
|
1166
|
+
idirs.concat(defaults.collect {|dir| dir + "/include"})
|
1167
|
+
idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
|
1168
|
+
end
|
1169
|
+
unless idirs.empty?
|
1170
|
+
idirs.collect! {|dir| "-I" + dir}
|
1171
|
+
idirs -= Shellwords.shellwords($CPPFLAGS)
|
1172
|
+
unless idirs.empty?
|
1173
|
+
$CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
|
1174
|
+
end
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
|
1178
|
+
if defaults
|
1179
|
+
ldirs.concat(defaults.collect {|dir| dir + "/lib"})
|
1180
|
+
ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
|
1181
|
+
end
|
1182
|
+
$LIBPATH = ldirs | $LIBPATH
|
1183
|
+
|
1184
|
+
[idir, ldir]
|
1185
|
+
end
|
1186
|
+
|
1187
|
+
# :stopdoc:
|
1188
|
+
|
1189
|
+
# Handles meta information about installed libraries. Uses your platform's
|
1190
|
+
# pkg-config program if it has one.
|
1191
|
+
def pkg_config(pkg)
|
1192
|
+
if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
|
1193
|
+
# iff package specific config command is given
|
1194
|
+
get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
|
1195
|
+
elsif ($PKGCONFIG ||=
|
1196
|
+
(pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
|
1197
|
+
find_executable0(pkgconfig) && pkgconfig) and
|
1198
|
+
system("#{$PKGCONFIG} --exists #{pkg}")
|
1199
|
+
# default to pkg-config command
|
1200
|
+
get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
|
1201
|
+
elsif find_executable0(pkgconfig = "#{pkg}-config")
|
1202
|
+
# default to package specific config command, as a last resort.
|
1203
|
+
get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
|
1204
|
+
end
|
1205
|
+
if get
|
1206
|
+
cflags = get['cflags']
|
1207
|
+
ldflags = get['libs']
|
1208
|
+
libs = get['libs-only-l']
|
1209
|
+
ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
|
1210
|
+
$CFLAGS += " " << cflags
|
1211
|
+
$LDFLAGS += " " << ldflags
|
1212
|
+
$libs += " " << libs
|
1213
|
+
Logging::message "package configuration for %s\n", pkg
|
1214
|
+
Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
|
1215
|
+
cflags, ldflags, libs
|
1216
|
+
[cflags, ldflags, libs]
|
1217
|
+
else
|
1218
|
+
Logging::message "package configuration for %s is not found\n", pkg
|
1219
|
+
nil
|
1220
|
+
end
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
def with_destdir(dir)
|
1224
|
+
dir = dir.sub($dest_prefix_pattern, '')
|
1225
|
+
/\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
# Converts forward slashes to backslashes. Aimed at MS Windows.
|
1229
|
+
#
|
1230
|
+
# Internal use only.
|
1231
|
+
#
|
1232
|
+
def winsep(s)
|
1233
|
+
s.tr('/', '\\')
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
# Converts native path to format acceptable in Makefile
|
1237
|
+
#
|
1238
|
+
# Internal use only.
|
1239
|
+
#
|
1240
|
+
if !CROSS_COMPILING
|
1241
|
+
case CONFIG['build_os']
|
1242
|
+
when 'mingw32'
|
1243
|
+
def mkintpath(path)
|
1244
|
+
# mingw uses make from msys and it needs special care
|
1245
|
+
# converts from C:\some\path to /C/some/path
|
1246
|
+
path = path.dup
|
1247
|
+
path.tr!('\\', '/')
|
1248
|
+
path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
|
1249
|
+
path
|
1250
|
+
end
|
1251
|
+
end
|
1252
|
+
end
|
1253
|
+
unless defined?(mkintpath)
|
1254
|
+
def mkintpath(path)
|
1255
|
+
path
|
1256
|
+
end
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
def configuration(srcdir)
|
1260
|
+
mk = []
|
1261
|
+
vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
|
1262
|
+
if !CROSS_COMPILING
|
1263
|
+
case CONFIG['build_os']
|
1264
|
+
when 'cygwin'
|
1265
|
+
if CONFIG['target_os'] != 'cygwin'
|
1266
|
+
vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
|
1267
|
+
end
|
1268
|
+
when 'msdosdjgpp'
|
1269
|
+
CONFIG['PATH_SEPARATOR'] = ';'
|
1270
|
+
end
|
1271
|
+
end
|
1272
|
+
mk << %{
|
1273
|
+
SHELL = /bin/sh
|
1274
|
+
|
1275
|
+
#### Start of system configuration section. ####
|
1276
|
+
#{
|
1277
|
+
if $extmk
|
1278
|
+
"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/")
|
1279
|
+
end
|
1280
|
+
}
|
1281
|
+
srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote}
|
1282
|
+
topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
|
1283
|
+
hdrdir = #{$extmk ? mkintpath(CONFIG["hdrdir"]).quote : '$(topdir)'}
|
1284
|
+
VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
|
1285
|
+
}
|
1286
|
+
if $extmk
|
1287
|
+
mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n"
|
1288
|
+
end
|
1289
|
+
if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1]
|
1290
|
+
mk << "\nDESTDIR = #{destdir}\n"
|
1291
|
+
end
|
1292
|
+
CONFIG.each do |key, var|
|
1293
|
+
next unless /prefix$/ =~ key
|
1294
|
+
mk << "#{key} = #{with_destdir(var)}\n"
|
1295
|
+
end
|
1296
|
+
CONFIG.each do |key, var|
|
1297
|
+
next if /^abs_/ =~ key
|
1298
|
+
next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1
|
1299
|
+
mk << "#{key} = #{with_destdir(var)}\n"
|
1300
|
+
end
|
1301
|
+
if !$extmk and !$configure_args.has_key?('--ruby') and
|
1302
|
+
sep = config_string('BUILD_FILE_SEPARATOR')
|
1303
|
+
sep = ":/=#{sep}"
|
1304
|
+
else
|
1305
|
+
sep = ""
|
1306
|
+
end
|
1307
|
+
extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" "
|
1308
|
+
mk << %{
|
1309
|
+
CC = #{CONFIG['CC']}
|
1310
|
+
LIBRUBY = #{CONFIG['LIBRUBY']}
|
1311
|
+
LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
|
1312
|
+
LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
|
1313
|
+
LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
|
1314
|
+
|
1315
|
+
RUBY_EXTCONF_H = #{$extconf_h}
|
1316
|
+
CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG
|
1317
|
+
INCFLAGS = -I. #$INCFLAGS
|
1318
|
+
DEFS = #{CONFIG['DEFS']}
|
1319
|
+
CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
|
1320
|
+
CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
|
1321
|
+
ldflags = #{$LDFLAGS}
|
1322
|
+
dldflags = #{$DLDFLAGS}
|
1323
|
+
archflag = #{$ARCH_FLAG}
|
1324
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
|
1325
|
+
LDSHARED = #{CONFIG['LDSHARED']}
|
1326
|
+
AR = #{CONFIG['AR']}
|
1327
|
+
EXEEXT = #{CONFIG['EXEEXT']}
|
1328
|
+
|
1329
|
+
RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
|
1330
|
+
RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
|
1331
|
+
arch = #{CONFIG['arch']}
|
1332
|
+
sitearch = #{CONFIG['sitearch']}
|
1333
|
+
ruby_version = #{Config::CONFIG['ruby_version']}
|
1334
|
+
ruby = #{$ruby}
|
1335
|
+
RUBY = $(ruby#{sep})
|
1336
|
+
RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
|
1337
|
+
MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
|
1338
|
+
INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
|
1339
|
+
INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
|
1340
|
+
INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
|
1341
|
+
COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
|
1342
|
+
|
1343
|
+
#### End of system configuration section. ####
|
1344
|
+
|
1345
|
+
preload = #{$preload ? $preload.join(' ') : ''}
|
1346
|
+
}
|
1347
|
+
if $nmake == ?b
|
1348
|
+
mk.each do |x|
|
1349
|
+
x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
|
1350
|
+
"!ifndef " + $1 + "\n" +
|
1351
|
+
$& +
|
1352
|
+
"!endif\n"
|
1353
|
+
end
|
1354
|
+
end
|
1355
|
+
end
|
1356
|
+
mk
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
def dummy_makefile(srcdir)
|
1360
|
+
configuration(srcdir) << <<RULES << CLEANINGS
|
1361
|
+
CLEANFILES = #{$cleanfiles.join(' ')}
|
1362
|
+
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
|
1363
|
+
|
1364
|
+
all install static install-so install-rb: Makefile
|
1365
|
+
|
1366
|
+
RULES
|
1367
|
+
end
|
1368
|
+
# :startdoc:
|
1369
|
+
|
1370
|
+
# Generates the Makefile for your extension, passing along any options and
|
1371
|
+
# preprocessor constants that you may have generated through other methods.
|
1372
|
+
#
|
1373
|
+
# The +target+ name should correspond the name of the global function name
|
1374
|
+
# defined within your C extension, minus the 'Init_'. For example, if your
|
1375
|
+
# C extension is defined as 'Init_foo', then your target would simply be 'foo'.
|
1376
|
+
#
|
1377
|
+
# If any '/' characters are present in the target name, only the last name
|
1378
|
+
# is interpreted as the target name, and the rest are considered toplevel
|
1379
|
+
# directory names, and the generated Makefile will be altered accordingly to
|
1380
|
+
# follow that directory structure.
|
1381
|
+
#
|
1382
|
+
# For example, if you pass 'test/foo' as a target name, your extension will
|
1383
|
+
# be installed under the 'test' directory. This means that in order to
|
1384
|
+
# load the file within a Ruby program later, that directory structure will
|
1385
|
+
# have to be followed, e.g. "require 'test/foo'".
|
1386
|
+
#
|
1387
|
+
# The +srcprefix+ should be used when your source files are not in the same
|
1388
|
+
# directory as your build script. This will not only eliminate the need for
|
1389
|
+
# you to manually copy the source files into the same directory as your build
|
1390
|
+
# script, but it also sets the proper +target_prefix+ in the generated
|
1391
|
+
# Makefile.
|
1392
|
+
#
|
1393
|
+
# Setting the +target_prefix+ will, in turn, install the generated binary in
|
1394
|
+
# a directory under your Config::CONFIG['sitearchdir'] that mimics your local
|
1395
|
+
# filesystem when you run 'make install'.
|
1396
|
+
#
|
1397
|
+
# For example, given the following file tree:
|
1398
|
+
#
|
1399
|
+
# ext/
|
1400
|
+
# extconf.rb
|
1401
|
+
# test/
|
1402
|
+
# foo.c
|
1403
|
+
#
|
1404
|
+
# And given the following code:
|
1405
|
+
#
|
1406
|
+
# create_makefile('test/foo', 'test')
|
1407
|
+
#
|
1408
|
+
# That will set the +target_prefix+ in the generated Makefile to 'test'. That,
|
1409
|
+
# in turn, will create the following file tree when installed via the
|
1410
|
+
# 'make install' command:
|
1411
|
+
#
|
1412
|
+
# /path/to/ruby/sitearchdir/test/foo.so
|
1413
|
+
#
|
1414
|
+
# It is recommended that you use this approach to generate your makefiles,
|
1415
|
+
# instead of copying files around manually, because some third party
|
1416
|
+
# libraries may depend on the +target_prefix+ being set properly.
|
1417
|
+
#
|
1418
|
+
# The +srcprefix+ argument can be used to override the default source
|
1419
|
+
# directory, i.e. the current directory . It is included as part of the VPATH
|
1420
|
+
# and added to the list of INCFLAGS.
|
1421
|
+
#
|
1422
|
+
def create_makefile(target, srcprefix = nil)
|
1423
|
+
$target = target
|
1424
|
+
libpath = $DEFLIBPATH|$LIBPATH
|
1425
|
+
message "creating Makefile\n"
|
1426
|
+
rm_f "conftest*"
|
1427
|
+
if CONFIG["DLEXT"] == $OBJEXT
|
1428
|
+
for lib in libs = $libs.split
|
1429
|
+
lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
|
1430
|
+
end
|
1431
|
+
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
|
1432
|
+
end
|
1433
|
+
|
1434
|
+
if target.include?('/')
|
1435
|
+
target_prefix, target = File.split(target)
|
1436
|
+
target_prefix[0,0] = '/'
|
1437
|
+
else
|
1438
|
+
target_prefix = ""
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
srcprefix ||= '$(srcdir)'
|
1442
|
+
Config::expand(srcdir = srcprefix.dup)
|
1443
|
+
|
1444
|
+
if not $objs
|
1445
|
+
$objs = []
|
1446
|
+
srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
|
1447
|
+
for f in srcs
|
1448
|
+
obj = File.basename(f, ".*") << ".o"
|
1449
|
+
$objs.push(obj) unless $objs.index(obj)
|
1450
|
+
end
|
1451
|
+
elsif !(srcs = $srcs)
|
1452
|
+
srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
|
1453
|
+
end
|
1454
|
+
$srcs = srcs
|
1455
|
+
for i in $objs
|
1456
|
+
i.sub!(/\.o\z/, ".#{$OBJEXT}")
|
1457
|
+
end
|
1458
|
+
$objs = $objs.join(" ")
|
1459
|
+
|
1460
|
+
target = nil if $objs == ""
|
1461
|
+
|
1462
|
+
if target and EXPORT_PREFIX
|
1463
|
+
if File.exist?(File.join(srcdir, target + '.def'))
|
1464
|
+
deffile = "$(srcdir)/$(TARGET).def"
|
1465
|
+
unless EXPORT_PREFIX.empty?
|
1466
|
+
makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
|
1467
|
+
end
|
1468
|
+
else
|
1469
|
+
makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
|
1470
|
+
end
|
1471
|
+
if makedef
|
1472
|
+
$distcleanfiles << '$(DEFFILE)'
|
1473
|
+
origdef = deffile
|
1474
|
+
deffile = "$(TARGET)-$(arch).def"
|
1475
|
+
end
|
1476
|
+
end
|
1477
|
+
origdef ||= ''
|
1478
|
+
|
1479
|
+
libpath = libpathflag(libpath)
|
1480
|
+
|
1481
|
+
dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
|
1482
|
+
staticlib = target ? "$(TARGET).#$LIBEXT" : ""
|
1483
|
+
mfile = open("Makefile", "wb")
|
1484
|
+
mfile.print configuration(srcprefix)
|
1485
|
+
mfile.print "
|
1486
|
+
libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
|
1487
|
+
LIBPATH = #{libpath}
|
1488
|
+
DEFFILE = #{deffile}
|
1489
|
+
|
1490
|
+
CLEANFILES = #{$cleanfiles.join(' ')}
|
1491
|
+
DISTCLEANFILES = #{$distcleanfiles.join(' ')}
|
1492
|
+
|
1493
|
+
extout = #{$extout}
|
1494
|
+
extout_prefix = #{$extout_prefix}
|
1495
|
+
target_prefix = #{target_prefix}
|
1496
|
+
LOCAL_LIBS = #{$LOCAL_LIBS}
|
1497
|
+
LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
|
1498
|
+
SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
|
1499
|
+
OBJS = #{$objs}
|
1500
|
+
TARGET = #{target}
|
1501
|
+
DLLIB = #{dllib}
|
1502
|
+
EXTSTATIC = #{$static || ""}
|
1503
|
+
STATIC_LIB = #{staticlib unless $static.nil?}
|
1504
|
+
#{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
|
1505
|
+
"
|
1506
|
+
install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
|
1507
|
+
n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
|
1508
|
+
mfile.print "
|
1509
|
+
TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
|
1510
|
+
CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
|
1511
|
+
CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak
|
1512
|
+
|
1513
|
+
all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
|
1514
|
+
static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
|
1515
|
+
"
|
1516
|
+
mfile.print CLEANINGS
|
1517
|
+
dirs = []
|
1518
|
+
mfile.print "install: install-so install-rb\n\n"
|
1519
|
+
sodir = (dir = "$(RUBYARCHDIR)").dup
|
1520
|
+
mfile.print("install-so: ")
|
1521
|
+
if target
|
1522
|
+
f = "$(DLLIB)"
|
1523
|
+
dest = "#{dir}/#{f}"
|
1524
|
+
mfile.puts dir, "install-so: #{dest}"
|
1525
|
+
unless $extout
|
1526
|
+
mfile.print "#{dest}: #{f}\n"
|
1527
|
+
if (sep = config_string('BUILD_FILE_SEPARATOR'))
|
1528
|
+
f.gsub!("/", sep)
|
1529
|
+
dir.gsub!("/", sep)
|
1530
|
+
sep = ":/="+sep
|
1531
|
+
f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
|
1532
|
+
f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
|
1533
|
+
dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
|
1534
|
+
dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
|
1535
|
+
end
|
1536
|
+
mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
|
1537
|
+
if defined?($installed_list)
|
1538
|
+
mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
|
1539
|
+
end
|
1540
|
+
end
|
1541
|
+
else
|
1542
|
+
mfile.puts "Makefile"
|
1543
|
+
end
|
1544
|
+
mfile.print("install-rb: pre-install-rb install-rb-default\n")
|
1545
|
+
mfile.print("install-rb-default: pre-install-rb-default\n")
|
1546
|
+
mfile.print("pre-install-rb: Makefile\n")
|
1547
|
+
mfile.print("pre-install-rb-default: Makefile\n")
|
1548
|
+
for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
|
1549
|
+
files = install_files(mfile, i, nil, srcprefix) or next
|
1550
|
+
for dir, *files in files
|
1551
|
+
unless dirs.include?(dir)
|
1552
|
+
dirs << dir
|
1553
|
+
mfile.print "pre-install-rb#{sfx}: #{dir}\n"
|
1554
|
+
end
|
1555
|
+
files.each do |f|
|
1556
|
+
dest = "#{dir}/#{File.basename(f)}"
|
1557
|
+
mfile.print("install-rb#{sfx}: #{dest}\n")
|
1558
|
+
mfile.print("#{dest}: #{f} #{dir}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
|
1559
|
+
sep = config_string('BUILD_FILE_SEPARATOR')
|
1560
|
+
if sep
|
1561
|
+
f = f.gsub("/", sep)
|
1562
|
+
sep = ":/="+sep
|
1563
|
+
f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
|
1564
|
+
f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
|
1565
|
+
else
|
1566
|
+
sep = ""
|
1567
|
+
end
|
1568
|
+
mfile.print("#{f} $(@D#{sep})\n")
|
1569
|
+
if defined?($installed_list) and !$extout
|
1570
|
+
mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
|
1571
|
+
end
|
1572
|
+
end
|
1573
|
+
end
|
1574
|
+
end
|
1575
|
+
dirs.unshift(sodir) if target and !dirs.include?(sodir)
|
1576
|
+
dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
|
1577
|
+
|
1578
|
+
mfile.print <<-SITEINSTALL
|
1579
|
+
|
1580
|
+
site-install: site-install-so site-install-rb
|
1581
|
+
site-install-so: install-so
|
1582
|
+
site-install-rb: install-rb
|
1583
|
+
|
1584
|
+
SITEINSTALL
|
1585
|
+
|
1586
|
+
return unless target
|
1587
|
+
|
1588
|
+
mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
|
1589
|
+
mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
|
1590
|
+
mfile.print "\n"
|
1591
|
+
|
1592
|
+
CXX_EXT.each do |ext|
|
1593
|
+
COMPILE_RULES.each do |rule|
|
1594
|
+
mfile.printf(rule, ext, $OBJEXT)
|
1595
|
+
mfile.printf("\n\t%s\n\n", COMPILE_CXX)
|
1596
|
+
end
|
1597
|
+
end
|
1598
|
+
%w[c].each do |ext|
|
1599
|
+
COMPILE_RULES.each do |rule|
|
1600
|
+
mfile.printf(rule, ext, $OBJEXT)
|
1601
|
+
mfile.printf("\n\t%s\n\n", COMPILE_C)
|
1602
|
+
end
|
1603
|
+
end
|
1604
|
+
|
1605
|
+
mfile.print "$(RUBYARCHDIR)/" if $extout
|
1606
|
+
mfile.print "$(DLLIB): "
|
1607
|
+
mfile.print "$(DEFFILE) " if makedef
|
1608
|
+
mfile.print "$(OBJS) Makefile\n"
|
1609
|
+
mfile.print "\t@-$(RM) $@\n"
|
1610
|
+
mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
|
1611
|
+
link_so = LINK_SO.gsub(/^/, "\t")
|
1612
|
+
mfile.print link_so, "\n\n"
|
1613
|
+
unless $static.nil?
|
1614
|
+
mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
|
1615
|
+
mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
|
1616
|
+
config_string('RANLIB') do |ranlib|
|
1617
|
+
mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
|
1618
|
+
end
|
1619
|
+
end
|
1620
|
+
mfile.print "\n\n"
|
1621
|
+
if makedef
|
1622
|
+
mfile.print "$(DEFFILE): #{origdef}\n"
|
1623
|
+
mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
|
1624
|
+
end
|
1625
|
+
|
1626
|
+
depend = File.join(srcdir, "depend")
|
1627
|
+
if File.exist?(depend)
|
1628
|
+
suffixes = []
|
1629
|
+
depout = []
|
1630
|
+
open(depend, "r") do |dfile|
|
1631
|
+
mfile.printf "###\n"
|
1632
|
+
cont = implicit = nil
|
1633
|
+
impconv = proc do
|
1634
|
+
COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
|
1635
|
+
implicit = nil
|
1636
|
+
end
|
1637
|
+
ruleconv = proc do |line|
|
1638
|
+
if implicit
|
1639
|
+
if /\A\t/ =~ line
|
1640
|
+
implicit[1] << line
|
1641
|
+
next
|
1642
|
+
else
|
1643
|
+
impconv[]
|
1644
|
+
end
|
1645
|
+
end
|
1646
|
+
if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
|
1647
|
+
suffixes << m[1] << m[2]
|
1648
|
+
implicit = [[m[1], m[2]], [m.post_match]]
|
1649
|
+
next
|
1650
|
+
elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
|
1651
|
+
line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
|
1652
|
+
end
|
1653
|
+
depout << line
|
1654
|
+
end
|
1655
|
+
while line = dfile.gets()
|
1656
|
+
line.gsub!(/\.o\b/, ".#{$OBJEXT}")
|
1657
|
+
line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
|
1658
|
+
if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
|
1659
|
+
(cont ||= []) << line
|
1660
|
+
next
|
1661
|
+
elsif cont
|
1662
|
+
line = (cont << line).join
|
1663
|
+
cont = nil
|
1664
|
+
end
|
1665
|
+
ruleconv.call(line)
|
1666
|
+
end
|
1667
|
+
if cont
|
1668
|
+
ruleconv.call(cont.join)
|
1669
|
+
elsif implicit
|
1670
|
+
impconv.call
|
1671
|
+
end
|
1672
|
+
end
|
1673
|
+
unless suffixes.empty?
|
1674
|
+
mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
|
1675
|
+
end
|
1676
|
+
mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h
|
1677
|
+
mfile.print depout
|
1678
|
+
else
|
1679
|
+
headers = %w[ruby.h defines.h]
|
1680
|
+
if RULE_SUBST
|
1681
|
+
headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
|
1682
|
+
end
|
1683
|
+
headers << $config_h if $config_h
|
1684
|
+
headers << "$(RUBY_EXTCONF_H)" if $extconf_h
|
1685
|
+
mfile.print "$(OBJS): ", headers.join(' '), "\n"
|
1686
|
+
end
|
1687
|
+
|
1688
|
+
$makefile_created = true
|
1689
|
+
ensure
|
1690
|
+
mfile.close if mfile
|
1691
|
+
end
|
1692
|
+
|
1693
|
+
# :stopdoc:
|
1694
|
+
|
1695
|
+
def init_mkmf(config = CONFIG)
|
1696
|
+
$makefile_created = false
|
1697
|
+
$arg_config = []
|
1698
|
+
$enable_shared = config['ENABLE_SHARED'] == 'yes'
|
1699
|
+
$defs = []
|
1700
|
+
$extconf_h = nil
|
1701
|
+
$CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
|
1702
|
+
$ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
|
1703
|
+
$CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
|
1704
|
+
$LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
|
1705
|
+
$INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)"
|
1706
|
+
$DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
|
1707
|
+
$LIBEXT = config['LIBEXT'].dup
|
1708
|
+
$OBJEXT = config["OBJEXT"].dup
|
1709
|
+
$LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
|
1710
|
+
$LIBRUBYARG = ""
|
1711
|
+
$LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
|
1712
|
+
$LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
|
1713
|
+
$DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"]
|
1714
|
+
$DEFLIBPATH.unshift(".")
|
1715
|
+
$LIBPATH = []
|
1716
|
+
$INSTALLFILES = []
|
1717
|
+
$NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
|
1718
|
+
|
1719
|
+
$objs = nil
|
1720
|
+
$srcs = nil
|
1721
|
+
$libs = ""
|
1722
|
+
if $enable_shared or Config.expand(config["LIBRUBY"].dup) != Config.expand(config["LIBRUBY_A"].dup)
|
1723
|
+
$LIBRUBYARG = config['LIBRUBYARG']
|
1724
|
+
end
|
1725
|
+
|
1726
|
+
$LOCAL_LIBS = ""
|
1727
|
+
|
1728
|
+
$cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
|
1729
|
+
$cleanfiles << "mkmf.log"
|
1730
|
+
$distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
|
1731
|
+
|
1732
|
+
$extout ||= nil
|
1733
|
+
$extout_prefix ||= nil
|
1734
|
+
|
1735
|
+
$arg_config.clear
|
1736
|
+
dir_config("opt")
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
FailedMessage = <<MESSAGE
|
1740
|
+
Could not create Makefile due to some reason, probably lack of
|
1741
|
+
necessary libraries and/or headers. Check the mkmf.log file for more
|
1742
|
+
details. You may need configuration options.
|
1743
|
+
|
1744
|
+
Provided configuration options:
|
1745
|
+
MESSAGE
|
1746
|
+
|
1747
|
+
# Returns whether or not the Makefile was successfully generated. If not,
|
1748
|
+
# the script will abort with an error message.
|
1749
|
+
#
|
1750
|
+
# Internal use only.
|
1751
|
+
#
|
1752
|
+
def mkmf_failed(path)
|
1753
|
+
unless $makefile_created or File.exist?("Makefile")
|
1754
|
+
opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
|
1755
|
+
abort "*** #{path} failed ***\n" + FailedMessage + opts.join
|
1756
|
+
end
|
1757
|
+
end
|
1758
|
+
|
1759
|
+
# :startdoc:
|
1760
|
+
|
1761
|
+
init_mkmf
|
1762
|
+
|
1763
|
+
$make = with_config("make-prog", ENV["MAKE"] || "make")
|
1764
|
+
make, = Shellwords.shellwords($make)
|
1765
|
+
$nmake = nil
|
1766
|
+
case
|
1767
|
+
when $mswin
|
1768
|
+
$nmake = ?m if /nmake/i =~ make
|
1769
|
+
when $bccwin
|
1770
|
+
$nmake = ?b if /Borland/i =~ `#{make} -h`
|
1771
|
+
end
|
1772
|
+
|
1773
|
+
Config::CONFIG["srcdir"] = CONFIG["srcdir"] =
|
1774
|
+
$srcdir = arg_config("--srcdir", File.dirname($0))
|
1775
|
+
$configure_args["--topsrcdir"] ||= $srcdir
|
1776
|
+
if $curdir = arg_config("--curdir")
|
1777
|
+
Config.expand(curdir = $curdir.dup)
|
1778
|
+
else
|
1779
|
+
curdir = $curdir = "."
|
1780
|
+
end
|
1781
|
+
unless File.expand_path(Config::CONFIG["topdir"]) == File.expand_path(curdir)
|
1782
|
+
CONFIG["topdir"] = $curdir
|
1783
|
+
Config::CONFIG["topdir"] = curdir
|
1784
|
+
end
|
1785
|
+
$configure_args["--topdir"] ||= $curdir
|
1786
|
+
$ruby = arg_config("--ruby", File.join(Config::CONFIG["bindir"], CONFIG["ruby_install_name"]))
|
1787
|
+
|
1788
|
+
split = Shellwords.method(:shellwords).to_proc
|
1789
|
+
|
1790
|
+
EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
|
1791
|
+
|
1792
|
+
hdr = []
|
1793
|
+
config_string('COMMON_MACROS') do |s|
|
1794
|
+
Shellwords.shellwords(s).each do |w|
|
1795
|
+
hdr << "#define " + w.split(/=/, 2).join(" ")
|
1796
|
+
end
|
1797
|
+
end
|
1798
|
+
config_string('COMMON_HEADERS') do |s|
|
1799
|
+
Shellwords.shellwords(s).each {|s| hdr << "#include <#{s}>"}
|
1800
|
+
end
|
1801
|
+
COMMON_HEADERS = hdr.join("\n")
|
1802
|
+
COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
|
1803
|
+
|
1804
|
+
COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
|
1805
|
+
RULE_SUBST = config_string('RULE_SUBST')
|
1806
|
+
COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<'
|
1807
|
+
COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<'
|
1808
|
+
TRY_LINK = config_string('TRY_LINK') ||
|
1809
|
+
"$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \
|
1810
|
+
"$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
|
1811
|
+
LINK_SO = config_string('LINK_SO') ||
|
1812
|
+
if CONFIG["DLEXT"] == $OBJEXT
|
1813
|
+
"ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
|
1814
|
+
else
|
1815
|
+
"$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
|
1816
|
+
"$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
|
1817
|
+
end
|
1818
|
+
LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
|
1819
|
+
RPATHFLAG = config_string('RPATHFLAG') || ''
|
1820
|
+
LIBARG = config_string('LIBARG') || '-l%s'
|
1821
|
+
|
1822
|
+
sep = config_string('BUILD_FILE_SEPARATOR') {|sep| ":/=#{sep}" if sep != "/"} || ""
|
1823
|
+
CLEANINGS = "
|
1824
|
+
clean:
|
1825
|
+
@-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})
|
1826
|
+
|
1827
|
+
distclean: clean
|
1828
|
+
@-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
1829
|
+
@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
|
1830
|
+
|
1831
|
+
realclean: distclean
|
1832
|
+
"
|
1833
|
+
|
1834
|
+
if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
|
1835
|
+
END {mkmf_failed($0)}
|
1836
|
+
end
|