rmagick 4.2.5 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +14 -0
  3. data/.devcontainer/ImageMagick6/devcontainer.json +11 -0
  4. data/.devcontainer/devcontainer.json +11 -0
  5. data/.devcontainer/setup-repo.sh +10 -0
  6. data/.devcontainer/setup-user.sh +45 -0
  7. data/.editorconfig +1 -1
  8. data/.github/workflows/ci.yml +90 -9
  9. data/.gitignore +4 -0
  10. data/.rubocop_todo.yml +16 -9
  11. data/.yardopts +1 -1
  12. data/CHANGELOG.md +141 -0
  13. data/Gemfile +20 -0
  14. data/README.md +12 -17
  15. data/Rakefile +63 -80
  16. data/before_install_linux.sh +4 -4
  17. data/before_install_osx.sh +7 -6
  18. data/ext/RMagick/extconf.rb +113 -52
  19. data/ext/RMagick/{rmagick.c → rmagick.cpp} +19 -22
  20. data/ext/RMagick/rmagick.h +88 -59
  21. data/ext/RMagick/rmagick_gvl.h +224 -0
  22. data/ext/RMagick/{rmdraw.c → rmdraw.cpp} +170 -159
  23. data/ext/RMagick/{rmenum.c → rmenum.cpp} +69 -50
  24. data/ext/RMagick/{rmfill.c → rmfill.cpp} +85 -24
  25. data/ext/RMagick/{rmilist.c → rmilist.cpp} +191 -93
  26. data/ext/RMagick/{rmimage.c → rmimage.cpp} +1544 -989
  27. data/ext/RMagick/{rminfo.c → rminfo.cpp} +140 -152
  28. data/ext/RMagick/{rmkinfo.c → rmkinfo.cpp} +46 -34
  29. data/ext/RMagick/rmmain.cpp +1923 -0
  30. data/ext/RMagick/{rmmontage.c → rmmontage.cpp} +50 -29
  31. data/ext/RMagick/{rmpixel.c → rmpixel.cpp} +108 -83
  32. data/ext/RMagick/{rmstruct.c → rmstruct.cpp} +6 -6
  33. data/ext/RMagick/{rmutil.c → rmutil.cpp} +62 -161
  34. data/lib/rmagick/version.rb +3 -1
  35. data/lib/rmagick.rb +2 -0
  36. data/lib/rmagick_internal.rb +76 -110
  37. data/lib/rvg/embellishable.rb +6 -2
  38. data/lib/rvg/misc.rb +7 -7
  39. data/lib/rvg/rvg.rb +2 -0
  40. data/lib/rvg/stretchable.rb +2 -2
  41. data/lib/rvg/transformable.rb +1 -1
  42. data/rmagick.gemspec +6 -17
  43. data/sig/rmagick/_draw_common_methods.rbs +64 -0
  44. data/sig/rmagick/_image_common_methods.rbs +389 -0
  45. data/sig/rmagick/draw.rbs +38 -0
  46. data/sig/rmagick/draw_attribute.rbs +28 -0
  47. data/sig/rmagick/enum.rbs +814 -0
  48. data/sig/rmagick/error.rbs +11 -0
  49. data/sig/rmagick/fill.rbs +21 -0
  50. data/sig/rmagick/geometry.rbs +14 -0
  51. data/sig/rmagick/image.rbs +194 -0
  52. data/sig/rmagick/image_list.rbs +181 -0
  53. data/sig/rmagick/iptc.rbs +101 -0
  54. data/sig/rmagick/kernel_info.rbs +12 -0
  55. data/sig/rmagick/optional_method_arguments.rbs +10 -0
  56. data/sig/rmagick/pixel.rbs +46 -0
  57. data/sig/rmagick/struct.rbs +90 -0
  58. data/sig/rmagick.rbs +43 -0
  59. data/sig/rvg/clippath.rbs +34 -0
  60. data/sig/rvg/container.rbs +78 -0
  61. data/sig/rvg/deep_equal.rbs +48 -0
  62. data/sig/rvg/describable.rbs +30 -0
  63. data/sig/rvg/embellishable.rbs +226 -0
  64. data/sig/rvg/misc.rbs +145 -0
  65. data/sig/rvg/paint.rbs +55 -0
  66. data/sig/rvg/pathdata.rbs +77 -0
  67. data/sig/rvg/rvg.rbs +125 -0
  68. data/sig/rvg/stretchable.rbs +56 -0
  69. data/sig/rvg/stylable.rbs +66 -0
  70. data/sig/rvg/text.rbs +118 -0
  71. data/sig/rvg/transformable.rbs +59 -0
  72. data/sig/rvg/units.rbs +33 -0
  73. metadata +63 -128
  74. data/.codeclimate.yml +0 -63
  75. data/deprecated/RMagick.rb +0 -6
  76. data/ext/RMagick/rmmain.c +0 -1951
data/Rakefile CHANGED
@@ -63,26 +63,13 @@ end
63
63
  desc 'Release'
64
64
  task release: %i[assert_clean_repo push_and_tag]
65
65
 
66
- desc 'Release and build the legacy way'
67
- task legacy_release: ['legacy:README.html', 'legacy:extconf', 'legacy:doc', 'legacy:manifest', 'release']
66
+ namespace :website do
67
+ PATH_TO_LOCAL_WEBSITE_REPOSITORY = File.expand_path('../rmagick.github.io')
68
68
 
69
- namespace :legacy do
70
- require 'find'
71
-
72
- task :redcloth do
73
- require 'redcloth'
74
- end
75
-
76
- README = 'README.html'
77
- MANIFEST = 'ext/RMagick/MANIFEST'
78
-
79
- # Change the version number placeholders in a file.
80
- # Returns an array of lines from the file.
81
- def reversion(name)
69
+ def replace_reversion(lines)
82
70
  now = Time.new
83
71
  now = now.strftime('%m/%d/%y')
84
72
 
85
- lines = File.readlines name
86
73
  lines.each do |line|
87
74
  line.gsub!(/0\.0\.0/, Magick::VERSION)
88
75
  line.gsub!(%r{YY/MM/DD}, now)
@@ -90,87 +77,83 @@ namespace :legacy do
90
77
  lines
91
78
  end
92
79
 
93
- # Rewrite a file containing embedded version number placeholders.
94
- def reversion_file(name)
95
- lines = reversion(name)
96
- tmp_name = name + '_tmp'
97
- mv name, tmp_name
98
- begin
99
- File.open(name, 'w') { |f| lines.each { |line| f.write line } }
100
- rescue StandardError
101
- mv tmp_name, name
102
- ensure
103
- rm tmp_name
104
- end
105
- end
106
-
107
- desc 'Update version in extconf'
108
- task :extconf do
109
- reversion_file 'ext/RMagick/extconf.rb'
80
+ def update_html(input_dir, output_dir, file_name)
81
+ lines = File.readlines(File.join(input_dir, file_name))
82
+ lines = replace_reversion(lines)
83
+ File.open(File.join(output_dir, file_name), 'w') { |f| lines.each { |line| f.write line } }
110
84
  end
111
85
 
112
- desc 'Build README.txt from README.textile using RedCloth'
113
- task 'README.txt' => [:redcloth] do
114
- reversion_file 'README.textile'
115
- body = File.readlines 'README.textile'
116
- body = RedCloth.new(body.join).to_html + "\n"
117
- File.open('README.txt', 'w') { |f| f.write body }
118
- end
119
-
120
- desc 'Build README.html from README.txt'
121
- task README => 'README.txt' do
122
- puts "writing #{README}"
123
- File.open(README, 'w') do |html|
124
- html.write <<~END_HTML_HEAD
125
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
126
- <html>
86
+ ENTITY = {
87
+ '&' => '&amp;',
88
+ '>' => '&gt;',
89
+ '<' => '&lt;'
90
+ }.freeze
91
+
92
+ def file_to_html(input_dir, input_file_name, output_dir, output_file_name)
93
+ File.open(File.join(input_dir, input_file_name)) do |src|
94
+ File.open(File.join(output_dir, output_file_name), 'w') do |dest|
95
+ dest.puts <<~END_EXHTMLHEAD
96
+ <!DOCTYPE public PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
97
+ <html xmlns="http://www.w3.org/1999/xhtml">
127
98
  <head>
128
- <title>RMagick #{Magick::VERSION} README</title>
129
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
130
- <meta name="GENERATOR" content="RedCloth">
99
+ <meta name="generator" content="ex2html.rb" />
100
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
101
+ <link rel="stylesheet" type="text/css" href="css/popup.css" />
102
+ <title>RMagick example: #{input_file_name}</title>
131
103
  </head>
132
104
  <body>
133
- END_HTML_HEAD
134
- html.write File.readlines('README.txt')
135
- html.write <<~END_HTML_TAIL
105
+ <h1>#{input_file_name}</h1>
106
+ <div class="bodybox">
107
+ <div class="bodyfloat">
108
+ <pre>
109
+ END_EXHTMLHEAD
110
+
111
+ src.each do |line|
112
+ line.gsub!(/[&><]/) { |s| ENTITY[s] }
113
+ dest.puts(line)
114
+ end
115
+
116
+ dest.puts <<~END_EXHTMLTAIL
117
+ </pre>
118
+ </div>
119
+ </div>
120
+ <div id="close"><a href="javascript:window.close();">Close window</a></div>
136
121
  </body>
137
- </html>
138
- END_HTML_TAIL
122
+ </html>
123
+ END_EXHTMLTAIL
124
+ end
139
125
  end
140
126
  end
141
127
 
142
- desc 'Update versions in html files'
143
- task :doc do
144
- Dir.chdir('doc') do
145
- FileList['*.html'].each { |d| reversion_file(d) }
128
+ desc 'Update RMagick website'
129
+ task :update do
130
+ unless File.exist?(PATH_TO_LOCAL_WEBSITE_REPOSITORY)
131
+ puts "Please clone the rmagick.github.io repository to #{PATH_TO_LOCAL_WEBSITE_REPOSITORY}"
132
+ exit 1
146
133
  end
147
- end
148
-
149
- # Remove files we don't want in the tarball.
150
- # Ensure files are not executable. (ref: bug #10080)
151
- desc "Remove files we don't want in the .gem; ensure files are not executable"
152
- task :fix_files do
153
- rm 'README.txt', verbose: true
154
- chmod 0o644, FileList['doc/*.html', 'doc/ex/*.rb', 'doc/ex/images/*', 'examples/*.rb']
155
- end
156
134
 
157
- desc 'Build manifest'
158
- task :manifest do
159
- now = Time.new
160
- now = now.strftime('%H:%M:%S %m/%d/%y')
161
- puts "generating #{MANIFEST}"
135
+ Dir.glob('doc/*.html') do |file|
136
+ update_html('doc', PATH_TO_LOCAL_WEBSITE_REPOSITORY, File.basename(file))
137
+ end
162
138
 
163
- File.open(MANIFEST, 'w') do |f|
164
- f.puts "MANIFEST for #{Magick::VERSION} - #{now}\n\n"
165
- Find.find('.') do |name|
166
- next if File.directory? name
139
+ Dir.glob('doc/ex/*.rb') do |file|
140
+ file_name = File.basename(file)
141
+ file_to_html('doc/ex', file_name, PATH_TO_LOCAL_WEBSITE_REPOSITORY, "#{file_name}.html")
142
+ end
143
+ end
144
+ end
167
145
 
168
- f.puts name[2..-1] # remove leading "./"
169
- end
146
+ namespace :rbs do
147
+ desc 'Validate RBS definitions'
148
+ task :validate do
149
+ all_sigs = Dir.glob('sig').map { |dir| "-I #{dir}" }.join(' ')
150
+ sh("bundle exec rbs #{all_sigs} validate") do |ok, _|
151
+ abort('one or more rbs validate failed') unless ok
170
152
  end
171
153
  end
172
154
  end
173
155
 
156
+ require 'bundler/gem_tasks'
174
157
  require 'rake/extensiontask'
175
158
  require 'rspec/core/rake_task'
176
159
  RSpec::Core::RakeTask.new(:spec)
@@ -2,7 +2,7 @@
2
2
 
3
3
  set -euox pipefail
4
4
 
5
- gem install bundler
5
+ gem install bundler -v 2.3.26 # Bundler 2.4.x has dropped support for Ruby 2.3
6
6
 
7
7
  if [ -v STYLE_CHECKS ]; then
8
8
  set +ux
@@ -24,7 +24,7 @@ sudo apt-get autoremove -y imagemagick* libmagick* --purge
24
24
  # install build tools, ImageMagick delegates
25
25
  sudo apt-get install -y build-essential libx11-dev libxext-dev zlib1g-dev \
26
26
  liblcms2-dev libpng-dev libjpeg-dev libfreetype6-dev libxml2-dev \
27
- libtiff5-dev libwebp-dev liblqr-1-0-dev vim gsfonts ghostscript ccache
27
+ libtiff5-dev libwebp-dev liblqr-1-0-dev vim gsfonts ghostscript
28
28
 
29
29
  if [ ! -d /usr/include/freetype ]; then
30
30
  # If `/usr/include/freetype` is not existed, ImageMagick 6.7 configuration fails about Freetype.
@@ -41,7 +41,7 @@ build_imagemagick() {
41
41
  mkdir -p build-ImageMagick
42
42
 
43
43
  version=(${IMAGEMAGICK_VERSION//./ })
44
- wget "https://imagemagick.org/download/releases/ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
44
+ wget "https://imagemagick.org/archive/releases/ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
45
45
  tar -xf "ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
46
46
  rm "ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
47
47
  mv "ImageMagick-${IMAGEMAGICK_VERSION}" "${build_dir}"
@@ -52,7 +52,7 @@ build_imagemagick() {
52
52
  fi
53
53
 
54
54
  cd "${build_dir}"
55
- CC="ccache cc" CXX="ccache c++" ./configure --prefix=/usr "${options}"
55
+ ./configure --prefix=/usr "${options}"
56
56
  make -j
57
57
  }
58
58
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  set -euox pipefail
4
4
 
5
- gem install bundler
5
+ gem install bundler -v 2.3.26 # Bundler 2.4.x has dropped support for Ruby 2.3
6
6
 
7
7
  if [ -v STYLE_CHECKS ]; then
8
8
  set +ux
@@ -16,10 +16,11 @@ if [ ! -v IMAGEMAGICK_VERSION ]; then
16
16
  fi
17
17
 
18
18
  export HOMEBREW_NO_AUTO_UPDATE=true
19
- brew install wget pkg-config ghostscript freetype jpeg little-cms2 libomp libpng libtiff liblqr libtool libxml2 zlib webp
19
+ brew uninstall --force imagemagick imagemagick@6
20
+ brew install wget ghostscript freetype jpeg little-cms2 openexr libomp libpng libtiff liblqr libtool zlib webp
20
21
 
21
- export LDFLAGS="-L/usr/local/opt/libxml2/lib -L/usr/local/opt/zlib/lib"
22
- export CPPFLAGS="-I/usr/local/opt/libxml2/include/libxml2 -I/usr/local/opt/zlib/include"
22
+ export LDFLAGS="-L$(brew --prefix libxml2)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix glib)/lib -L$(brew --prefix openexr)/lib"
23
+ export CPPFLAGS="-I$(brew --prefix libxml2)/include -I$(brew --prefix zlib)/include -I$(brew --prefix glib)/include/glib-2.0 -I$(brew --prefix glib)/lib/glib-2.0/include -I$(brew --prefix openexr)/include/OpenEXR"
23
24
 
24
25
  project_dir=$(pwd)
25
26
  build_dir="${project_dir}/build-ImageMagick/ImageMagick-${IMAGEMAGICK_VERSION}"
@@ -31,7 +32,7 @@ build_imagemagick() {
31
32
  mkdir -p build-ImageMagick
32
33
 
33
34
  version=(${IMAGEMAGICK_VERSION//./ })
34
- wget "https://imagemagick.org/download/releases/ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
35
+ wget "https://imagemagick.org/archive/releases/ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
35
36
  tar -xf "ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
36
37
  rm "ImageMagick-${IMAGEMAGICK_VERSION}.tar.xz"
37
38
  mv "ImageMagick-${IMAGEMAGICK_VERSION}" "${build_dir}"
@@ -42,7 +43,7 @@ build_imagemagick() {
42
43
  fi
43
44
 
44
45
  cd "${build_dir}"
45
- ./configure --prefix=/usr/local "${options}"
46
+ ./configure --prefix=/usr/local "${options}" --without-raw --without-jxl --without-openjp2
46
47
  make -j
47
48
  }
48
49
 
@@ -2,6 +2,13 @@ lib_dir = File.expand_path('../../lib', File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
3
3
  require 'rubygems'
4
4
  require 'mkmf'
5
+ require 'pkg-config'
6
+
7
+ module MakeMakefile
8
+ # Use the C++ compiler to retrieve the information needed to create a Makefile for mswin environment.
9
+ remove_const(:CONFTEST_C)
10
+ CONFTEST_C = "#{CONFTEST}.cpp"
11
+ end
5
12
 
6
13
  module RMagick
7
14
  class Extconf
@@ -9,6 +16,33 @@ module RMagick
9
16
  RMAGICK_VERS = ::Magick::VERSION
10
17
  MIN_RUBY_VERS = ::Magick::MIN_RUBY_VERSION
11
18
 
19
+ # ImageMagick 6.7 package
20
+ IM6_7_PACKAGES = ['ImageMagick'].freeze
21
+
22
+ # ImageMagick 6.8+ packages
23
+ IM6_PACKAGES = %w[
24
+ ImageMagick-6.Q64HDRI
25
+ ImageMagick-6.Q32HDRI
26
+ ImageMagick-6.Q16HDRI
27
+ ImageMagick-6.Q8HDRI
28
+ ImageMagick-6.Q64
29
+ ImageMagick-6.Q32
30
+ ImageMagick-6.Q16
31
+ ImageMagick-6.Q8
32
+ ].freeze
33
+
34
+ # ImageMagick 7 packages
35
+ IM7_PACKAGES = %w[
36
+ ImageMagick-7.Q64HDRI
37
+ ImageMagick-7.Q32HDRI
38
+ ImageMagick-7.Q16HDRI
39
+ ImageMagick-7.Q8HDRI
40
+ ImageMagick-7.Q64
41
+ ImageMagick-7.Q32
42
+ ImageMagick-7.Q16
43
+ ImageMagick-7.Q8
44
+ ].freeze
45
+
12
46
  attr_reader :headers
13
47
 
14
48
  def initialize
@@ -24,16 +58,17 @@ module RMagick
24
58
  return if RUBY_PLATFORM =~ /mswin|mingw/
25
59
 
26
60
  if find_executable('brew')
27
- pkg_config_path = "#{`brew --prefix imagemagick@6`.strip}/lib/pkgconfig"
61
+ append_pkg_config_path("#{`brew --prefix imagemagick`.strip}/lib/pkgconfig")
62
+ append_pkg_config_path("#{`brew --prefix imagemagick@6`.strip}/lib/pkgconfig")
28
63
  elsif find_executable('pacman')
29
- pkg_config_path = '/usr/lib/imagemagick6/pkgconfig'
30
- else
31
- return
64
+ append_pkg_config_path('/usr/lib/imagemagick6/pkgconfig')
32
65
  end
66
+ end
33
67
 
68
+ def append_pkg_config_path(path)
34
69
  pkg_config_paths = ENV['PKG_CONFIG_PATH'].to_s.split(':')
35
- if File.exist?(pkg_config_path) && !pkg_config_paths.include?(pkg_config_path)
36
- ENV['PKG_CONFIG_PATH'] = [ENV['PKG_CONFIG_PATH'], pkg_config_path].compact.join(':')
70
+ if File.exist?(path) && !pkg_config_paths.include?(path)
71
+ ENV['PKG_CONFIG_PATH'] = [ENV['PKG_CONFIG_PATH'], path].compact.join(':')
37
72
  end
38
73
  end
39
74
 
@@ -49,7 +84,7 @@ module RMagick
49
84
  end
50
85
 
51
86
  def configure_headers
52
- @headers = %w[assert.h ctype.h stdio.h stdlib.h math.h time.h sys/types.h]
87
+ @headers = %w[assert.h ctype.h stdio.h stdlib.h math.h time.h sys/types.h ruby.h ruby/io.h]
53
88
 
54
89
  if have_header('MagickCore/MagickCore.h')
55
90
  headers << 'MagickCore/MagickCore.h'
@@ -67,17 +102,21 @@ module RMagick
67
102
  check_multiple_imagemagick_versions
68
103
  check_partial_imagemagick_versions
69
104
 
70
- libdir = `pkg-config --libs-only-L #{$magick_package}`.chomp.sub('-L', '')
71
- ldflags = "#{ENV['LDFLAGS']} " + `pkg-config --libs #{$magick_package}`.chomp
105
+ original_ldflags = $LDFLAGS.dup
106
+
107
+ libdir = PKGConfig.libs_only_L($magick_package).chomp.sub('-L', '')
108
+ ldflags = "#{ENV['LDFLAGS']} " + PKGConfig.libs($magick_package).chomp
109
+ rpath = libdir.empty? ? '' : "-Wl,-rpath,#{libdir}"
72
110
 
73
111
  # Save flags
74
- $CPPFLAGS = "#{ENV['CPPFLAGS']} " + `pkg-config --cflags #{$magick_package}`.chomp
75
- $LOCAL_LIBS = "#{ENV['LIBS']} " + `pkg-config --libs #{$magick_package}`.chomp
76
- $LDFLAGS = "#{ldflags} -Wl,-rpath,#{libdir}"
112
+ $CPPFLAGS += " #{ENV['CPPFLAGS']} " + PKGConfig.cflags($magick_package).chomp
113
+ $CPPFLAGS += ' -x c++ -std=c++11 -Wno-register'
114
+ $LOCAL_LIBS += " #{ENV['LIBS']} " + PKGConfig.libs($magick_package).chomp
115
+ $LDFLAGS += " #{ldflags} #{rpath}"
77
116
 
78
117
  unless try_link("int main() { }")
79
118
  # if linker does not recognizes '-Wl,-rpath,somewhere' option, it revert to original option
80
- $LDFLAGS = ldflags
119
+ $LDFLAGS = "#{original_ldflags} #{ldflags}"
81
120
  end
82
121
 
83
122
  configure_archflags_for_osx($magick_package) if RUBY_PLATFORM =~ /darwin/ # osx
@@ -85,8 +124,9 @@ module RMagick
85
124
  elsif RUBY_PLATFORM =~ /mingw/ # mingw
86
125
 
87
126
  dir_paths = search_paths_for_library_for_windows
88
- $CPPFLAGS = %(-I"#{dir_paths[:include]}")
89
- $LDFLAGS = %(-L"#{dir_paths[:lib]}")
127
+ $CPPFLAGS += %( -I"#{dir_paths[:include]}")
128
+ $CPPFLAGS += ' -x c++ -std=c++11 -Wno-register'
129
+ $LDFLAGS += %( -L"#{dir_paths[:lib]}")
90
130
  $LDFLAGS << ' -lucrt' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
91
131
 
92
132
  have_library(im_version_at_least?('7.0.0') ? 'CORE_RL_MagickCore_' : 'CORE_RL_magick_')
@@ -98,11 +138,13 @@ module RMagick
98
138
  $LDFLAGS << %( -libpath:"#{dir_paths[:lib]}")
99
139
  $LDFLAGS << ' -libpath:ucrt' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
100
140
 
101
- $LOCAL_LIBS = im_version_at_least?('7.0.0') ? 'CORE_RL_MagickCore_.lib' : 'CORE_RL_magick_.lib'
141
+ $LOCAL_LIBS += ' ' + (im_version_at_least?('7.0.0') ? 'CORE_RL_MagickCore_.lib' : 'CORE_RL_magick_.lib')
102
142
 
143
+ $CPPFLAGS += ' /std:c++11'
103
144
  end
104
-
105
- $CPPFLAGS << (have_macro('__GNUC__') ? ' -std=gnu99' : ' -std=c99')
145
+ ruby_version = RUBY_VERSION.split('.')
146
+ $CPPFLAGS += " -DRUBY_VERSION_MAJOR=#{ruby_version[0]} -DRUBY_VERSION_MINOR=#{ruby_version[1]}"
147
+ $CPPFLAGS += ' $(optflags) $(debugflags)'
106
148
  end
107
149
 
108
150
  def exit_failure(msg)
@@ -122,31 +164,40 @@ module RMagick
122
164
  exit(1)
123
165
  end
124
166
 
167
+ def detect_imagemagick_packages(packages)
168
+ packages.select do |package|
169
+ PKGConfig.exist?(package)
170
+ end
171
+ end
172
+
173
+ def installed_im6_packages
174
+ @installed_im6_packages ||= detect_imagemagick_packages(IM6_PACKAGES)
175
+ end
176
+
177
+ def installed_im7_packages
178
+ @installed_im7_packages ||= detect_imagemagick_packages(IM7_PACKAGES)
179
+ end
180
+
125
181
  def determine_imagemagick_package
126
- packages = `pkg-config --list-all`.scan(/(ImageMagick\-[\.A-Z0-9]+) .*/).flatten
182
+ packages = [installed_im7_packages, installed_im6_packages].flatten
127
183
 
128
- # For ancient version of ImageMagick 6 we need a different regex
129
184
  if packages.empty?
130
- packages = `pkg-config --list-all`.scan(/(ImageMagick) .*/).flatten
185
+ # ImageMagick 6.7 does not have package file like ImageMagick-6.Q16.pc
186
+ packages = detect_imagemagick_packages(IM6_7_PACKAGES)
131
187
  end
132
188
 
133
189
  if packages.empty?
134
190
  exit_failure "Can't install RMagick #{RMAGICK_VERS}. Can't find ImageMagick with pkg-config\n"
135
191
  end
136
192
 
137
- if packages.length > 1
138
-
139
- im7_packages = packages.grep(/\AImageMagick-7/)
140
-
141
- if im7_packages.any?
142
- checking_for('forced use of ImageMagick 6') do
143
- if ENV['USE_IMAGEMAGICK_6']
144
- packages -= im7_packages
145
- true
146
- else
147
- packages = im7_packages
148
- false
149
- end
193
+ if installed_im6_packages.any? && installed_im7_packages.any?
194
+ checking_for('forced use of ImageMagick 6') do
195
+ if ENV['USE_IMAGEMAGICK_6']
196
+ packages = installed_im6_packages
197
+ true
198
+ else
199
+ packages = installed_im7_packages
200
+ false
150
201
  end
151
202
  end
152
203
  end
@@ -218,7 +269,7 @@ module RMagick
218
269
  # issue #169
219
270
  # set ARCHFLAGS appropriately for OSX
220
271
  def configure_archflags_for_osx(magick_package)
221
- return unless `pkg-config #{magick_package} --libs-only-L`.match(%r{-L(.+)/lib})
272
+ return unless PKGConfig.libs_only_L(magick_package).match(%r{-L(.+)/lib})
222
273
 
223
274
  imagemagick_dir = Regexp.last_match(1)
224
275
  command = Dir.glob(File.join(imagemagick_dir, "bin/*")).select { |file| File.executable? file }.first
@@ -261,10 +312,8 @@ module RMagick
261
312
  exit_failure <<~END_MINGW
262
313
  Can't install RMagick #{RMAGICK_VERS}.
263
314
  Can't find the ImageMagick library.
264
- Retry with '--with-opt-dir' option.
265
- Usage: gem install rmagick -- '--with-opt-dir=\"[path to ImageMagick]\"'
266
- e.g.
267
- gem install rmagick -- '--with-opt-dir=\"C:\\Program Files\\ImageMagick-6.9.1-Q16\"'
315
+
316
+ Please check PATH environment variable for ImageMagick installation path.
268
317
  END_MINGW
269
318
  end
270
319
 
@@ -272,9 +321,9 @@ module RMagick
272
321
  assert_minimum_ruby_version!
273
322
  assert_has_dev_libs!
274
323
 
275
- # Check for compiler. Extract first word so ENV['CC'] can be a program name with arguments.
276
- cc = (ENV['CC'] || RbConfig::CONFIG['CC'] || 'gcc').split(' ').first
277
- exit_failure "No C compiler found in ${ENV['PATH']}. See mkmf.log for details." unless find_executable(cc)
324
+ # Check for compiler. Extract first word so ENV['CXX'] can be a program name with arguments.
325
+ cxx = (ENV['CXX'] || RbConfig::CONFIG['CXX'] || 'g++').split(' ').first
326
+ exit_failure "No C++ compiler found in ${ENV['PATH']}. See mkmf.log for details." unless find_executable(cxx)
278
327
  end
279
328
 
280
329
  def assert_minimum_ruby_version!
@@ -293,16 +342,12 @@ module RMagick
293
342
  END_FAILURE
294
343
 
295
344
  if RUBY_PLATFORM !~ /mswin|mingw/
296
- unless find_executable('pkg-config')
297
- exit_failure "Can't install RMagick #{RMAGICK_VERS}. Can't find pkg-config in #{ENV['PATH']}\n"
298
- end
299
-
300
- unless `pkg-config --libs MagickCore`[/\bl\s*(MagickCore|Magick)6?\b/]
345
+ unless PKGConfig.libs('MagickCore')[/\bl\s*(MagickCore|Magick)6?\b/]
301
346
  exit_failure failure_message
302
347
  end
303
348
 
304
349
  $magick_package = determine_imagemagick_package
305
- $magick_version = `pkg-config #{$magick_package} --modversion`[/^(\d+\.\d+\.\d+)/]
350
+ $magick_version = PKGConfig.modversion($magick_package)[/^(\d+\.\d+\.\d+)/]
306
351
  else
307
352
  `#{magick_command} -version` =~ /Version: ImageMagick (\d+\.\d+\.\d+)-+\d+ /
308
353
  $magick_version = Regexp.last_match(1)
@@ -320,7 +365,9 @@ module RMagick
320
365
 
321
366
  def create_header_file
322
367
  ruby_api = [
323
- 'rb_gc_adjust_memory_usage' # Ruby 2.4.0
368
+ 'rb_gc_adjust_memory_usage', # Ruby 2.4.0
369
+ 'rb_gc_mark_movable', # Ruby 2.7.0
370
+ 'rb_io_path' # Ruby 3.2.0
324
371
  ]
325
372
  memory_api = %w[
326
373
  posix_memalign
@@ -359,9 +406,6 @@ module RMagick
359
406
 
360
407
  def create_makefile_file
361
408
  create_header_file
362
- # Prior to 1.8.5 mkmf duplicated the symbols on the command line and in the
363
- # extconf.h header. Suppress that behavior by removing the symbol array.
364
- $defs = []
365
409
 
366
410
  # Force re-compilation if the generated Makefile changed.
367
411
  $config_h = 'Makefile'
@@ -370,6 +414,22 @@ module RMagick
370
414
  print_summary
371
415
  end
372
416
 
417
+ def create_compile_flags_txt
418
+ cppflags = $CPPFLAGS.split(' ')
419
+ include_flags = cppflags.select { |flag| flag.start_with?('-I') }
420
+ define_flags = cppflags.select { |flag| flag.start_with?('-D') } + $defs
421
+
422
+ File.open('compile_flags.txt', 'w') do |f|
423
+ include_flags.each { |flag| f.puts(flag) }
424
+ f.puts "-I#{Dir.pwd}"
425
+ f.puts "-I#{RbConfig::CONFIG['rubyhdrdir']}"
426
+ f.puts "-I#{RbConfig::CONFIG['rubyhdrdir']}/ruby/backward"
427
+ f.puts "-I#{RbConfig::CONFIG['rubyarchhdrdir']}"
428
+ f.puts "-std=c++11"
429
+ define_flags.each { |flag| f.puts(flag) }
430
+ end
431
+ end
432
+
373
433
  def magick_command
374
434
  @magick_command ||= if find_executable('magick')
375
435
  'magick'
@@ -408,3 +468,4 @@ at_exit do
408
468
  message msg + "\n"
409
469
  end
410
470
  extconf.create_makefile_file
471
+ extconf.create_compile_flags_txt