mini_portile2 2.8.1 → 2.8.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d467d59c8fe3298a010263ffcf5de58be5ba9be7757dbce500fd96251a2c864e
4
- data.tar.gz: 70534d0b13bcdc0fe91c5524f8d40414ee1cc29fc357806aea4bbe52cc39129b
3
+ metadata.gz: 999335cad76fefd8e0ec313bb0bd7260a0259ef37760a01ee34153754ea2661f
4
+ data.tar.gz: 472586aad90ab8c61df7fffd60f6507206d3900fb71d505edef100ceef6e7e2f
5
5
  SHA512:
6
- metadata.gz: d67bc2e58d7fa53a4315fdaa1ab56f8ca5fe6b0a42e020b511e3aef3f7185690fbb51ee8f1bd5ccec48f0b37ef9037f45d7c56973ae3fdffadcfddc8679b6594
7
- data.tar.gz: f2ab11a49573096c9b7fe150d1fcde07161a36514b6bb885e455f82cf270a70465987b131d359e898bd99850c616989afcbf48a9de1b5dbfb46831f9eea46f42
6
+ metadata.gz: c978de2664efdee0bd9b89a842d33844c7ab6ee5d9dce45baaa53e061ab04777fcfb0ecc4900b772e4a2cf64c80c615b727d1227f9d09e223e30834f1dbf5ddc
7
+ data.tar.gz: 58a18c5ee2c34ab370dd0d30449aa2bf06e40d7e070ab1bd5e8fcf4226e8e390516718b2b6aed0e17ee3736aa04eea45917cee53a5a1b117b78ffcb12dc4bfd3
@@ -25,7 +25,7 @@ jobs:
25
25
  fail-fast: false
26
26
  matrix:
27
27
  platform: [ubuntu-latest, windows-latest, macos-latest]
28
- ruby: ["2.3", "2.4", "2.5", "2.6", "2.7", "3.0", "3.1", "head"]
28
+ ruby: ["2.3", "2.4", "2.5", "2.6", "2.7", "3.0", "3.1", "3.2", "head"]
29
29
  runs-on: ${{ matrix.platform }}
30
30
  steps:
31
31
  - name: configure git crlf on windows
@@ -33,7 +33,7 @@ jobs:
33
33
  run: |
34
34
  git config --system core.autocrlf false
35
35
  git config --system core.eol lf
36
- - uses: actions/checkout@v2
36
+ - uses: actions/checkout@v3
37
37
  - uses: MSP-Greg/setup-ruby-pkgs@v1
38
38
  with:
39
39
  apt-get: _update_ build-essential cmake
@@ -57,14 +57,14 @@ jobs:
57
57
  run: |
58
58
  git config --system core.autocrlf false
59
59
  git config --system core.eol lf
60
- - uses: actions/checkout@v2
60
+ - uses: actions/checkout@v3
61
61
  - uses: MSP-Greg/setup-ruby-pkgs@v1
62
62
  with:
63
63
  apt-get: _update_ build-essential cmake
64
64
  mingw: _upgrade_ cmake
65
65
  ruby-version: ${{ matrix.ruby }}
66
66
  bundler-cache: true
67
- - uses: actions/cache@v2
67
+ - uses: actions/cache@v3
68
68
  with:
69
69
  path: examples/ports/archives
70
70
  key: ${{ matrix.platform }}-examples-${{ hashFiles('examples/Rakefile') }}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  ## mini_portile changelog
2
2
 
3
+ ### 2.8.4 / 2023-07-18
4
+
5
+ - cmake: set CMAKE compile flags to configure cross-compilation similarly to `autotools` `--host` flag: `SYSTEM_NAME`, `SYSTEM_PROCESSOR`, `C_COMPILER`, and `CXX_COMPILER`. [#130] (Thanks, @stanhu!)
6
+
7
+
8
+ ### 2.8.3 / 2023-07-18
9
+
10
+ #### Fixed
11
+
12
+ - cmake: only use MSYS/NMake generators when available. [#129] (Thanks, @stanhu!)
13
+
14
+
15
+ ### 2.8.2 / 2023-04-30
16
+
17
+ #### Fixed
18
+
19
+ - Ensure that the `source_directory` option will work when given a Windows path to an autoconf directory. [#126]
20
+
21
+
3
22
  ### 2.8.1 / 2022-12-24
4
23
 
5
24
  #### Fixed
@@ -35,17 +35,45 @@ class MiniPortile
35
35
  attr_accessor :host, :files, :patch_files, :target, :logger, :source_directory
36
36
 
37
37
  def self.windows?
38
- RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
38
+ target_os =~ /mswin|mingw/
39
39
  end
40
40
 
41
41
  # GNU MinGW compiled Ruby?
42
42
  def self.mingw?
43
- RbConfig::CONFIG['target_os'] =~ /mingw/
43
+ target_os =~ /mingw/
44
44
  end
45
45
 
46
46
  # MS Visual-C compiled Ruby?
47
47
  def self.mswin?
48
- RbConfig::CONFIG['target_os'] =~ /mswin/
48
+ target_os =~ /mswin/
49
+ end
50
+
51
+ def self.darwin?
52
+ target_os =~ /darwin/
53
+ end
54
+
55
+ def self.freebsd?
56
+ target_os =~ /freebsd/
57
+ end
58
+
59
+ def self.openbsd?
60
+ target_os =~ /openbsd/
61
+ end
62
+
63
+ def self.linux?
64
+ target_os =~ /linux/
65
+ end
66
+
67
+ def self.solaris?
68
+ target_os =~ /solaris/
69
+ end
70
+
71
+ def self.target_os
72
+ RbConfig::CONFIG['target_os']
73
+ end
74
+
75
+ def self.target_cpu
76
+ RbConfig::CONFIG['target_cpu']
49
77
  end
50
78
 
51
79
  def initialize(name, version, **kwargs)
@@ -67,12 +95,12 @@ class MiniPortile
67
95
  end
68
96
 
69
97
  def source_directory=(path)
70
- @source_directory = File.expand_path(path)
98
+ @source_directory = posix_path(path)
71
99
  end
72
100
 
73
101
  def prepare_build_directory
74
102
  raise "source_directory is not set" if source_directory.nil?
75
- output "Building #{@name} #{@version} from source at '#{source_directory}'"
103
+ output "Building #{@name} from source at '#{source_directory}'"
76
104
  FileUtils.mkdir_p(File.join(tmp_path, [name, version].join("-")))
77
105
  FileUtils.rm_rf(port_path) # make sure we always re-install
78
106
  end
@@ -137,7 +165,7 @@ class MiniPortile
137
165
  # Windows doesn't recognize the shebang.
138
166
  command.unshift("sh")
139
167
  end
140
- execute('configure', command + computed_options)
168
+ execute('configure', command + computed_options, altlog: "config.log")
141
169
  end
142
170
 
143
171
  def compile
@@ -200,10 +228,7 @@ class MiniPortile
200
228
 
201
229
  output "Activating #{@name} #{@version} (from #{port_path})..."
202
230
  vars.each do |var, path|
203
- full_path = File.expand_path(path)
204
-
205
- # turn into a valid Windows path (if required)
206
- full_path.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
231
+ full_path = native_path(path)
207
232
 
208
233
  # save current variable value
209
234
  old_value = ENV[var] || ''
@@ -237,7 +262,25 @@ class MiniPortile
237
262
  (ENV["MAKE"] || @make_command || ENV["make"] || "make").dup
238
263
  end
239
264
 
240
- private
265
+ private
266
+
267
+ def native_path(path)
268
+ path = File.expand_path(path)
269
+ if File::ALT_SEPARATOR
270
+ path.tr(File::SEPARATOR, File::ALT_SEPARATOR)
271
+ else
272
+ path
273
+ end
274
+ end
275
+
276
+ def posix_path(path)
277
+ path = File.expand_path(path)
278
+ if File::ALT_SEPARATOR
279
+ "/" + path.tr(File::ALT_SEPARATOR, File::SEPARATOR).tr(":", File::SEPARATOR)
280
+ else
281
+ path
282
+ end
283
+ end
241
284
 
242
285
  def tmp_path
243
286
  "tmp/#{@host}/ports/#{@name}/#{@version}"
@@ -420,6 +463,7 @@ private
420
463
  opt_debug = command_opts.fetch(:debug, false)
421
464
  opt_cd = command_opts.fetch(:cd) { work_path }
422
465
  opt_env = command_opts.fetch(:env) { Hash.new }
466
+ opt_altlog = command_opts.fetch(:altlog, nil)
423
467
 
424
468
  log_out = log_file(action)
425
469
 
@@ -450,12 +494,12 @@ private
450
494
  output "OK"
451
495
  return true
452
496
  else
453
- if File.exist? log_out
454
- output "ERROR, review '#{log_out}' to see what happened. Last lines are:"
455
- output("=" * 72)
456
- log_lines = File.readlines(log_out)
457
- output(log_lines[-[log_lines.length, 20].min .. -1])
458
- output("=" * 72)
497
+ output "ERROR. Please review logs to see what happened:\n"
498
+ [log_out, opt_altlog].compact.each do |log|
499
+ next unless File.exist?(log)
500
+ output("----- contents of '#{log}' -----")
501
+ output(File.read(log))
502
+ output("----- end of file -----")
459
503
  end
460
504
  raise "Failed to complete #{action} task"
461
505
  end
@@ -1,6 +1,9 @@
1
1
  require 'mini_portile2/mini_portile'
2
+ require 'open3'
2
3
 
3
4
  class MiniPortileCMake < MiniPortile
5
+ attr_accessor :system_name
6
+
4
7
  def configure_prefix
5
8
  "-DCMAKE_INSTALL_PREFIX=#{File.expand_path(port_path)}"
6
9
  end
@@ -11,13 +14,10 @@ class MiniPortileCMake < MiniPortile
11
14
  end
12
15
 
13
16
  def configure_defaults
14
- if MiniPortile.mswin?
15
- ['-G', 'NMake Makefiles']
16
- elsif MiniPortile.mingw?
17
- ['-G', 'MSYS Makefiles']
18
- else
19
- []
20
- end
17
+ [
18
+ generator_defaults,
19
+ cmake_compile_flags,
20
+ ].flatten
21
21
  end
22
22
 
23
23
  def configure
@@ -48,4 +48,91 @@ class MiniPortileCMake < MiniPortile
48
48
  def cmake_cmd
49
49
  (ENV["CMAKE"] || @cmake_command || "cmake").dup
50
50
  end
51
+
52
+ private
53
+
54
+ def generator_defaults
55
+ if MiniPortile.mswin? && generator_available?('NMake')
56
+ ['-G', 'NMake Makefiles']
57
+ elsif MiniPortile.mingw? && generator_available?('MSYS')
58
+ ['-G', 'MSYS Makefiles']
59
+ else
60
+ []
61
+ end
62
+ end
63
+
64
+ def cmake_compile_flags
65
+ c_compiler, cxx_compiler = find_c_and_cxx_compilers(host)
66
+
67
+ # needed to ensure cross-compilation with CMake targets the right CPU and compilers
68
+ [
69
+ "-DCMAKE_SYSTEM_NAME=#{cmake_system_name}",
70
+ "-DCMAKE_SYSTEM_PROCESSOR=#{cpu_type}",
71
+ "-DCMAKE_C_COMPILER=#{c_compiler}",
72
+ "-DCMAKE_CXX_COMPILER=#{cxx_compiler}"
73
+ ]
74
+ end
75
+
76
+ def find_compiler(compilers)
77
+ compilers.find { |binary| which(binary) }
78
+ end
79
+
80
+ # configure automatically searches for the right compiler based on the
81
+ # `--host` parameter. However, CMake doesn't have an equivalent feature.
82
+ # Search for the right compiler for the target architecture using
83
+ # some basic heruistics.
84
+ def find_c_and_cxx_compilers(host)
85
+ c_compiler = ENV["CC"]
86
+ cxx_compiler = ENV["CXX"]
87
+
88
+ if MiniPortile.darwin?
89
+ c_compiler ||= 'clang'
90
+ cxx_compiler ||='clang++'
91
+ else
92
+ c_compiler ||= 'gcc'
93
+ cxx_compiler ||= 'g++'
94
+ end
95
+
96
+ c_platform_compiler = "#{host}-#{c_compiler}"
97
+ cxx_platform_compiler = "#{host}-#{cxx_compiler}"
98
+ c_compiler = find_compiler([c_platform_compiler, c_compiler])
99
+ cxx_compiler = find_compiler([cxx_platform_compiler, cxx_compiler])
100
+
101
+ [c_compiler, cxx_compiler]
102
+ end
103
+
104
+ # Full list: https://gitlab.kitware.com/cmake/cmake/-/blob/v3.26.4/Modules/CMakeDetermineSystem.cmake?ref_type=tags#L12-31
105
+ def cmake_system_name
106
+ return system_name if system_name
107
+
108
+ if MiniPortile.linux?
109
+ 'Linux'
110
+ elsif MiniPortile.darwin?
111
+ 'Darwin'
112
+ elsif MiniPortile.windows?
113
+ 'Windows'
114
+ elsif MiniPortile.freebsd?
115
+ 'FreeBSD'
116
+ elsif MiniPortile.openbsd?
117
+ 'OpenBSD'
118
+ elsif MiniPortile.solaris?
119
+ 'SunOS'
120
+ else
121
+ raise "Unable to set CMAKE_SYSTEM_NAME for #{MiniPortile.target_os}"
122
+ end
123
+ end
124
+
125
+ def generator_available?(generator_type)
126
+ stdout_str, status = Open3.capture2("#{cmake_cmd} --help")
127
+
128
+ raise 'Unable to determine whether CMake supports #{generator_type} Makefile generator' unless status.success?
129
+
130
+ stdout_str.include?("#{generator_type} Makefiles")
131
+ end
132
+
133
+ def cpu_type
134
+ return 'x86_64' if MiniPortile.target_cpu == 'x64'
135
+
136
+ MiniPortile.target_cpu
137
+ end
51
138
  end
@@ -1,3 +1,3 @@
1
1
  class MiniPortile
2
- VERSION = "2.8.1"
2
+ VERSION = "2.8.4"
3
3
  end
data/test/test_cmake.rb CHANGED
@@ -14,13 +14,11 @@ class TestCMake < TestCase
14
14
  create_tar(@tar_path, @assets_path, "test-cmake-1.0")
15
15
  start_webrick(File.dirname(@tar_path))
16
16
 
17
- @recipe = MiniPortileCMake.new("test-cmake", "1.0").tap do |recipe|
18
- recipe.files << "http://localhost:#{HTTP_PORT}/#{ERB::Util.url_encode(File.basename(@tar_path))}"
19
- recipe.patch_files << File.join(@assets_path, "patch 1.diff")
20
- git_dir = File.join(@assets_path, "git")
21
- with_custom_git_dir(git_dir) do
22
- recipe.cook
23
- end
17
+ @recipe = init_recipe
18
+
19
+ git_dir = File.join(@assets_path, "git")
20
+ with_custom_git_dir(git_dir) do
21
+ recipe.cook
24
22
  end
25
23
  end
26
24
 
@@ -57,9 +55,16 @@ class TestCMake < TestCase
57
55
  binary = File.join(recipe.path, "bin", exe_name)
58
56
  assert File.exist?(binary), binary
59
57
  end
58
+
59
+ def init_recipe
60
+ MiniPortileCMake.new("test-cmake", "1.0").tap do |recipe|
61
+ recipe.files << "http://localhost:#{HTTP_PORT}/#{ERB::Util.url_encode(File.basename(@tar_path))}"
62
+ recipe.patch_files << File.join(@assets_path, "patch 1.diff")
63
+ end
64
+ end
60
65
  end
61
66
 
62
- class TestCMakeConfig < TestCase
67
+ class TestCMakeConfig < TestCMake
63
68
  def test_make_command_configuration
64
69
  MiniPortile.stub(:mswin?, false) do
65
70
  without_env("MAKE") do
@@ -77,6 +82,107 @@ class TestCMakeConfig < TestCase
77
82
  end
78
83
  end
79
84
 
85
+ def test_configure_defaults_with_macos
86
+ recipe = init_recipe
87
+ recipe.host = 'some-host'
88
+
89
+ with_env({ "CC" => nil, "CXX" => nil }) do
90
+ MiniPortile.stub(:darwin?, true) do
91
+ with_stubbed_target(os: 'darwin22', cpu: 'arm64') do
92
+ with_compilers(recipe, host_prefix: true, c_compiler: 'clang', cxx_compiler: 'clang++') do
93
+ Open3.stub(:capture2, cmake_help_mock('Unix')) do
94
+ assert_equal(
95
+ [
96
+ "-DCMAKE_SYSTEM_NAME=Darwin",
97
+ "-DCMAKE_SYSTEM_PROCESSOR=arm64",
98
+ "-DCMAKE_C_COMPILER=some-host-clang",
99
+ "-DCMAKE_CXX_COMPILER=some-host-clang++"
100
+ ],
101
+ recipe.configure_defaults)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ def test_configure_defaults_with_manual_system_name
110
+ recipe = init_recipe
111
+ recipe.system_name = 'Custom'
112
+
113
+ MiniPortile.stub(:darwin?, false) do
114
+ with_stubbed_target do
115
+ with_compilers(recipe) do
116
+ Open3.stub(:capture2, cmake_help_mock('Unix')) do
117
+ assert_equal(
118
+ [
119
+ "-DCMAKE_SYSTEM_NAME=Custom",
120
+ "-DCMAKE_SYSTEM_PROCESSOR=x86_64",
121
+ "-DCMAKE_C_COMPILER=gcc",
122
+ "-DCMAKE_CXX_COMPILER=g++"
123
+ ],
124
+ recipe.configure_defaults)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ def test_configure_defaults_with_unix_makefiles
132
+ recipe = init_recipe
133
+
134
+ MiniPortile.stub(:linux?, true) do
135
+ MiniPortile.stub(:darwin?, false) do
136
+ with_stubbed_target do
137
+ with_compilers(recipe) do
138
+ Open3.stub(:capture2, cmake_help_mock('Unix')) do
139
+ MiniPortile.stub(:mingw?, true) do
140
+ assert_equal(default_x86_compile_flags,
141
+ recipe.configure_defaults)
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ def test_configure_defaults_with_msys_makefiles
151
+ recipe = init_recipe
152
+
153
+ MiniPortile.stub(:linux?, true) do
154
+ MiniPortile.stub(:darwin?, false) do
155
+ with_stubbed_target do
156
+ with_compilers(recipe) do
157
+ Open3.stub(:capture2, cmake_help_mock('MSYS')) do
158
+ MiniPortile.stub(:mingw?, true) do
159
+ assert_equal(['-G', 'MSYS Makefiles'] + default_x86_compile_flags, recipe.configure_defaults)
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ def test_configure_defaults_with_nmake_makefiles
169
+ recipe = init_recipe
170
+
171
+ MiniPortile.stub(:linux?, true) do
172
+ MiniPortile.stub(:darwin?, false) do
173
+ with_stubbed_target do
174
+ with_compilers(recipe) do
175
+ Open3.stub(:capture2, cmake_help_mock('NMake')) do
176
+ MiniPortile.stub(:mswin?, true) do
177
+ assert_equal(['-G', 'NMake Makefiles'] + default_x86_compile_flags, recipe.configure_defaults)
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+
80
186
  def test_cmake_command_configuration
81
187
  without_env("CMAKE") do
82
188
  assert_equal("cmake", MiniPortileCMake.new("test", "1.0.0").cmake_cmd)
@@ -87,4 +193,55 @@ class TestCMakeConfig < TestCase
87
193
  assert_equal("asdf", MiniPortileCMake.new("test", "1.0.0", cmake_command: "xyzzy").cmake_cmd)
88
194
  end
89
195
  end
196
+
197
+ private
198
+
199
+ def with_stubbed_target(os: 'linux', cpu: 'x86_64')
200
+ MiniPortile.stub(:target_os, os) do
201
+ MiniPortile.stub(:target_cpu, cpu) do
202
+ yield
203
+ end
204
+ end
205
+ end
206
+
207
+ def with_compilers(recipe, host_prefix: false, c_compiler: 'gcc', cxx_compiler: 'g++')
208
+ mock = MiniTest::Mock.new
209
+
210
+ if host_prefix
211
+ mock.expect(:call, true, ["#{recipe.host}-#{c_compiler}"])
212
+ mock.expect(:call, true, ["#{recipe.host}-#{cxx_compiler}"])
213
+ else
214
+ mock.expect(:call, false, ["#{recipe.host}-#{c_compiler}"])
215
+ mock.expect(:call, true, [c_compiler])
216
+ mock.expect(:call, false, ["#{recipe.host}-#{cxx_compiler}"])
217
+ mock.expect(:call, true, [cxx_compiler])
218
+ end
219
+
220
+ recipe.stub(:which, mock) do
221
+ yield
222
+ end
223
+ end
224
+
225
+ def default_x86_compile_flags
226
+ [
227
+ "-DCMAKE_SYSTEM_NAME=Linux",
228
+ "-DCMAKE_SYSTEM_PROCESSOR=x86_64",
229
+ "-DCMAKE_C_COMPILER=gcc",
230
+ "-DCMAKE_CXX_COMPILER=g++"
231
+ ]
232
+ end
233
+
234
+ def cmake_help_mock(generator_type)
235
+ open3_mock = MiniTest::Mock.new
236
+ cmake_script = <<~SCRIPT
237
+ echo "The following generators are available on this platform (* marks default):"
238
+ echo "* #{generator_type} Makefiles = Generates standard #{generator_type.upcase} makefiles."
239
+ SCRIPT
240
+
241
+ exit_status = MiniTest::Mock.new
242
+ exit_status.expect(:success?, true)
243
+ expected_output = [cmake_script, exit_status]
244
+ open3_mock.expect(:call, expected_output, ['cmake --help'])
245
+ open3_mock
246
+ end
90
247
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_portile2
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.1
4
+ version: 2.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luis Lavena
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-12-24 00:00:00.000000000 Z
13
+ date: 2023-07-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
153
  - !ruby/object:Gem::Version
154
154
  version: '0'
155
155
  requirements: []
156
- rubygems_version: 3.3.26
156
+ rubygems_version: 3.4.10
157
157
  signing_key:
158
158
  specification_version: 4
159
159
  summary: Simplistic port-like solution for developers