rmagick 4.2.5 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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