mini_portile2 2.8.0 → 2.8.9

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.
@@ -5,9 +5,11 @@ require 'fileutils'
5
5
  require 'tempfile'
6
6
  require 'digest'
7
7
  require 'open-uri'
8
- require 'cgi'
8
+ require "cgi/escape"
9
+ require "cgi/util" if RUBY_VERSION < "3.5"
9
10
  require 'rbconfig'
10
11
  require 'shellwords'
12
+ require 'open3'
11
13
 
12
14
  # Monkey patch for Net::HTTP by ruby open-uri fix:
13
15
  # https://github.com/ruby/ruby/commit/58835a9
@@ -27,25 +29,73 @@ class Net::HTTP
27
29
  end
28
30
  end
29
31
 
32
+ $MINI_PORTILE_STATIC_LIBS = {}
33
+
30
34
  class MiniPortile
31
35
  DEFAULT_TIMEOUT = 10
32
36
 
33
- attr_reader :name, :version, :original_host
37
+ attr_reader :name, :version, :original_host, :source_directory
34
38
  attr_writer :configure_options
35
- attr_accessor :host, :files, :patch_files, :target, :logger, :source_directory
39
+ attr_accessor :host, :files, :patch_files, :target, :logger
36
40
 
37
41
  def self.windows?
38
- RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
42
+ target_os =~ /mswin|mingw/
39
43
  end
40
44
 
41
45
  # GNU MinGW compiled Ruby?
42
46
  def self.mingw?
43
- RbConfig::CONFIG['target_os'] =~ /mingw/
47
+ target_os =~ /mingw/
44
48
  end
45
49
 
46
50
  # MS Visual-C compiled Ruby?
47
51
  def self.mswin?
48
- RbConfig::CONFIG['target_os'] =~ /mswin/
52
+ target_os =~ /mswin/
53
+ end
54
+
55
+ def self.darwin?
56
+ target_os =~ /darwin/
57
+ end
58
+
59
+ def self.freebsd?
60
+ target_os =~ /freebsd/
61
+ end
62
+
63
+ def self.openbsd?
64
+ target_os =~ /openbsd/
65
+ end
66
+
67
+ def self.linux?
68
+ target_os =~ /linux/
69
+ end
70
+
71
+ def self.solaris?
72
+ target_os =~ /solaris/
73
+ end
74
+
75
+ def self.target_os
76
+ RbConfig::CONFIG['target_os']
77
+ end
78
+
79
+ def self.target_cpu
80
+ RbConfig::CONFIG['target_cpu']
81
+ end
82
+
83
+ def self.native_path(path)
84
+ path = File.expand_path(path)
85
+ if File::ALT_SEPARATOR
86
+ path.tr(File::SEPARATOR, File::ALT_SEPARATOR)
87
+ else
88
+ path
89
+ end
90
+ end
91
+
92
+ def self.posix_path(path)
93
+ path = File.expand_path(path)
94
+ if File::ALT_SEPARATOR
95
+ "/" + path.tr(File::ALT_SEPARATOR, File::SEPARATOR).tr(":", File::SEPARATOR)
96
+ else
97
+ path
98
+ end
49
99
  end
50
100
 
51
101
  def initialize(name, version, **kwargs)
@@ -55,24 +105,25 @@ class MiniPortile
55
105
  @files = []
56
106
  @patch_files = []
57
107
  @log_files = {}
58
- @logger = STDOUT
108
+ @logger = kwargs[:logger] || STDOUT
59
109
  @source_directory = nil
60
110
 
61
- @original_host = @host = detect_host
62
-
63
- @gcc_command = kwargs[:gcc_command]
111
+ @cc_command = kwargs[:cc_command] || kwargs[:gcc_command]
112
+ @cxx_command = kwargs[:cxx_command]
64
113
  @make_command = kwargs[:make_command]
65
114
  @open_timeout = kwargs[:open_timeout] || DEFAULT_TIMEOUT
66
115
  @read_timeout = kwargs[:read_timeout] || DEFAULT_TIMEOUT
116
+
117
+ @original_host = @host = detect_host
67
118
  end
68
119
 
69
120
  def source_directory=(path)
70
- @source_directory = File.expand_path(path)
121
+ @source_directory = posix_path(path)
71
122
  end
72
123
 
73
124
  def prepare_build_directory
74
125
  raise "source_directory is not set" if source_directory.nil?
75
- output "Building #{@name} #{@version} from source at '#{source_directory}'"
126
+ output "Building #{@name} from source at '#{source_directory}'"
76
127
  FileUtils.mkdir_p(File.join(tmp_path, [name, version].join("-")))
77
128
  FileUtils.rm_rf(port_path) # make sure we always re-install
78
129
  end
@@ -99,9 +150,9 @@ class MiniPortile
99
150
  when which('git')
100
151
  lambda { |file|
101
152
  message "Running git apply with #{file}... "
102
- # By --work-tree=. git-apply uses the current directory as
103
- # the project root and will not search upwards for .git.
104
- execute('patch', ["git", "--git-dir=.", "--work-tree=.", "apply", "--whitespace=warn", file], :initial_message => false)
153
+ Dir.mktmpdir do |tmp_git_dir|
154
+ execute('patch', ["git", "--git-dir=#{tmp_git_dir}", "--work-tree=.", "apply", "--whitespace=warn", file], :initial_message => false)
155
+ end
105
156
  }
106
157
  when which('patch')
107
158
  lambda { |file|
@@ -137,7 +188,7 @@ class MiniPortile
137
188
  # Windows doesn't recognize the shebang.
138
189
  command.unshift("sh")
139
190
  end
140
- execute('configure', command + computed_options)
191
+ execute('configure', command + computed_options, altlog: "config.log")
141
192
  end
142
193
 
143
194
  def compile
@@ -191,19 +242,15 @@ class MiniPortile
191
242
  end
192
243
 
193
244
  def activate
194
- lib_path = File.join(port_path, "lib")
195
245
  vars = {
196
246
  'PATH' => File.join(port_path, 'bin'),
197
- 'CPATH' => File.join(port_path, 'include'),
198
- 'LIBRARY_PATH' => lib_path
247
+ 'CPATH' => include_path,
248
+ 'LIBRARY_PATH' => lib_path,
199
249
  }.reject { |env, path| !File.directory?(path) }
200
250
 
201
251
  output "Activating #{@name} #{@version} (from #{port_path})..."
202
252
  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
253
+ full_path = native_path(path)
207
254
 
208
255
  # save current variable value
209
256
  old_value = ENV[var] || ''
@@ -215,7 +262,7 @@ class MiniPortile
215
262
 
216
263
  # rely on LDFLAGS when cross-compiling
217
264
  if File.exist?(lib_path) && (@host != @original_host)
218
- full_path = File.expand_path(lib_path)
265
+ full_path = native_path(lib_path)
219
266
 
220
267
  old_value = ENV.fetch("LDFLAGS", "")
221
268
 
@@ -225,19 +272,129 @@ class MiniPortile
225
272
  end
226
273
  end
227
274
 
275
+ # pkg: the pkg-config file name (without the .pc extension)
276
+ # dir: inject the directory path for the pkg-config file (probably only useful for tests)
277
+ # static: the name of the static library archive (without the "lib" prefix or the file extension), or nil for dynamic linking
278
+ #
279
+ # we might be able to be terribly clever and infer the name of the static archive file, but
280
+ # unfortunately projects have so much freedom in what they can report (for name, for libs, etc.)
281
+ # that it feels unreliable to try to do so, so I'm preferring to just have the developer make it
282
+ # explicit.
283
+ def mkmf_config(pkg: nil, dir: nil, static: nil)
284
+ require "mkmf"
285
+
286
+ if pkg
287
+ dir ||= File.join(lib_path, "pkgconfig")
288
+ pcfile = File.join(dir, "#{pkg}.pc")
289
+ unless File.exist?(pcfile)
290
+ raise ArgumentError, "pkg-config file '#{pcfile}' does not exist"
291
+ end
292
+
293
+ output "Configuring MakeMakefile for #{File.basename(pcfile)} (in #{File.dirname(pcfile)})\n"
294
+
295
+ # on macos, pkg-config will not return --cflags without this
296
+ ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t"
297
+
298
+ # append to PKG_CONFIG_PATH as we go, so later pkg-config files can depend on earlier ones
299
+ ENV["PKG_CONFIG_PATH"] = [ENV["PKG_CONFIG_PATH"], dir].compact.join(File::PATH_SEPARATOR)
300
+
301
+ incflags = minimal_pkg_config(pcfile, "cflags-only-I")
302
+ cflags = minimal_pkg_config(pcfile, "cflags-only-other")
303
+ if static
304
+ ldflags = minimal_pkg_config(pcfile, "libs-only-L", "static")
305
+ libflags = minimal_pkg_config(pcfile, "libs-only-l", "static")
306
+ else
307
+ ldflags = minimal_pkg_config(pcfile, "libs-only-L")
308
+ libflags = minimal_pkg_config(pcfile, "libs-only-l")
309
+ end
310
+ else
311
+ output "Configuring MakeMakefile for #{@name} #{@version} (from #{path})\n"
312
+
313
+ lib_name = name.sub(/\Alib/, "") # TODO: use delete_prefix when we no longer support ruby 2.4
314
+
315
+ incflags = Dir.exist?(include_path) ? "-I#{include_path}" : ""
316
+ cflags = ""
317
+ ldflags = Dir.exist?(lib_path) ? "-L#{lib_path}" : ""
318
+ libflags = Dir.exist?(lib_path) ? "-l#{lib_name}" : ""
319
+ end
320
+
321
+ if static
322
+ libdir = lib_path
323
+ if pcfile
324
+ pcfile_libdir = minimal_pkg_config(pcfile, "variable=libdir").strip
325
+ libdir = pcfile_libdir unless pcfile_libdir.empty?
326
+ end
327
+
328
+ #
329
+ # keep track of the libraries we're statically linking against, and fix up ldflags and
330
+ # libflags to make sure we link statically against the recipe's libaries.
331
+ #
332
+ # this avoids the unintentionally dynamically linking against system libraries, and makes sure
333
+ # that if multiple pkg-config files reference each other that we are able to intercept flags
334
+ # from dependent packages that reference the static archive.
335
+ #
336
+ $MINI_PORTILE_STATIC_LIBS[static] = libdir
337
+ static_ldflags = $MINI_PORTILE_STATIC_LIBS.values.map { |v| "-L#{v}" }
338
+ static_libflags = $MINI_PORTILE_STATIC_LIBS.keys.map { |v| "-l#{v}" }
339
+
340
+ # remove `-L#{libdir}` and `-lfoo`. we don't need them since we link against the static
341
+ # archive using the full path.
342
+ ldflags = ldflags.shellsplit.reject { |f| static_ldflags.include?(f) }.shelljoin
343
+ libflags = libflags.shellsplit.reject { |f| static_libflags.include?(f) }.shelljoin
344
+
345
+ # prepend the full path to the static archive to the linker flags
346
+ static_archive = File.join(libdir, "lib#{static}.#{$LIBEXT}")
347
+ libflags = [static_archive, libflags].join(" ").strip
348
+ end
349
+
350
+ # prefer this package by prepending to search paths and library flags
351
+ #
352
+ # convert the ldflags into a list of directories and append to $LIBPATH (instead of just using
353
+ # $LDFLAGS) to ensure we get the `-Wl,-rpath` linker flag for re-finding shared libraries.
354
+ $INCFLAGS = [incflags, $INCFLAGS].join(" ").strip
355
+ libpaths = ldflags.shellsplit.map { |f| f.sub(/\A-L/, "") }
356
+ $LIBPATH = libpaths | $LIBPATH
357
+ $libs = [libflags, $libs].join(" ").strip
358
+
359
+ # prefer this package's compiler flags by appending them to the command line
360
+ $CFLAGS = [$CFLAGS, cflags].join(" ").strip
361
+ $CXXFLAGS = [$CXXFLAGS, cflags].join(" ").strip
362
+ end
363
+
228
364
  def path
229
365
  File.expand_path(port_path)
230
366
  end
231
367
 
232
- def gcc_cmd
233
- (ENV["CC"] || @gcc_command || RbConfig::CONFIG["CC"] || "gcc").dup
368
+ def include_path
369
+ File.join(path, "include")
370
+ end
371
+
372
+ def lib_path
373
+ File.join(path, "lib")
374
+ end
375
+
376
+ def cc_cmd
377
+ (ENV["CC"] || @cc_command || RbConfig::CONFIG["CC"] || "gcc").dup
378
+ end
379
+ alias :gcc_cmd :cc_cmd
380
+
381
+ def cxx_cmd
382
+ (ENV["CXX"] || @cxx_command || RbConfig::CONFIG["CXX"] || "g++").dup
234
383
  end
235
384
 
236
385
  def make_cmd
237
386
  (ENV["MAKE"] || @make_command || ENV["make"] || "make").dup
238
387
  end
239
388
 
240
- private
389
+ private
390
+
391
+ def native_path(path)
392
+ MiniPortile.native_path(path)
393
+ end
394
+
395
+ def posix_path(path)
396
+ MiniPortile.posix_path(path)
397
+ end
241
398
 
242
399
  def tmp_path
243
400
  "tmp/#{@host}/ports/#{@name}/#{@version}"
@@ -306,24 +463,29 @@ private
306
463
  gpg_exe = which('gpg2') || which('gpg') || raise("Neither GPG nor GPG2 is installed")
307
464
 
308
465
  # import the key into our own keyring
309
- gpg_status = IO.popen([gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--import"], "w+") do |io|
310
- io.write gpg[:key]
311
- io.close_write
312
- io.read
466
+ gpg_error = nil
467
+ gpg_status = Open3.popen3(gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--import") do |gpg_in, gpg_out, gpg_err, _thread|
468
+ gpg_in.write gpg[:key]
469
+ gpg_in.close
470
+ gpg_error = gpg_err.read
471
+ gpg_out.read
313
472
  end
314
473
  key_ids = gpg_status.scan(/\[GNUPG:\] IMPORT_OK \d+ (?<key_id>[0-9a-f]+)/i).map(&:first)
315
- raise "invalid gpg key provided" if key_ids.empty?
474
+ raise "invalid gpg key provided:\n#{gpg_error}" if key_ids.empty?
316
475
 
317
- # verify the signature against our keyring
318
- gpg_status = IO.popen([gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--verify", signature_file, file[:local_path]], &:read)
319
-
320
- # remove the key from our keyring
321
- key_ids.each do |key_id|
322
- IO.popen([gpg_exe, "--batch", "--yes", "--no-default-keyring", "--keyring", KEYRING_NAME, "--delete-keys", key_id], &:read)
323
- raise "unable to delete the imported key" unless $?.exitstatus==0
476
+ begin
477
+ # verify the signature against our keyring
478
+ gpg_status, gpg_error, _status = Open3.capture3(gpg_exe, "--status-fd", "1", "--no-default-keyring", "--keyring", KEYRING_NAME, "--verify", signature_file, file[:local_path])
479
+
480
+ raise "signature mismatch:\n#{gpg_error}" unless gpg_status.match(/^\[GNUPG:\] VALIDSIG/)
481
+ ensure
482
+ # remove the key from our keyring
483
+ key_ids.each do |key_id|
484
+ IO.popen([gpg_exe, "--batch", "--yes", "--no-default-keyring", "--keyring", KEYRING_NAME, "--delete-keys", key_id], &:read)
485
+ raise "unable to delete the imported key" unless $?.exitstatus==0
486
+ end
324
487
  end
325
488
 
326
- raise "signature mismatch" unless gpg_status.match(/^\[GNUPG:\] VALIDSIG/)
327
489
 
328
490
  else
329
491
  digest = case
@@ -347,30 +509,6 @@ private
347
509
  }
348
510
  end
349
511
 
350
- TAR_EXECUTABLES = %w[gtar bsdtar tar basic-bsdtar]
351
- def tar_exe
352
- @@tar_exe ||= begin
353
- TAR_EXECUTABLES.find { |c|
354
- which(c)
355
- } or raise("tar not found - please make sure that one of the following commands is in the PATH: #{TAR_EXECUTABLES.join(", ")}")
356
- end
357
- end
358
-
359
- def tar_compression_switch(filename)
360
- case File.extname(filename)
361
- when '.gz', '.tgz'
362
- 'z'
363
- when '.bz2', '.tbz2'
364
- 'j'
365
- when '.xz'
366
- 'J'
367
- when '.Z'
368
- 'Z'
369
- else
370
- ''
371
- end
372
- end
373
-
374
512
  # From: http://stackoverflow.com/a/5471032/7672
375
513
  # Thanks, Mislav!
376
514
  #
@@ -397,6 +535,8 @@ private
397
535
  output = `#{gcc_cmd} -v 2>&1`
398
536
  if m = output.match(/^Target\: (.*)$/)
399
537
  @detect_host = m[1]
538
+ else
539
+ @detect_host = nil
400
540
  end
401
541
 
402
542
  @detect_host
@@ -405,12 +545,39 @@ private
405
545
  end
406
546
  end
407
547
 
548
+ TAR_EXECUTABLES = %w[gtar bsdtar tar basic-bsdtar]
549
+ def tar_exe
550
+ @@tar_exe ||= begin
551
+ TAR_EXECUTABLES.find { |c|
552
+ which(c)
553
+ } or raise("tar not found - please make sure that one of the following commands is in the PATH: #{TAR_EXECUTABLES.join(", ")}")
554
+ end
555
+ end
556
+
557
+ def xzcat_exe
558
+ @@xzcat_exe ||= which("xzcat") ? "xzcat" : raise("xzcat not found")
559
+ end
560
+
561
+ def tar_command(file, target)
562
+ case File.extname(file)
563
+ when '.gz', '.tgz'
564
+ [tar_exe, 'xzf', file, '-C', target]
565
+ when '.bz2', '.tbz2'
566
+ [tar_exe, 'xjf', file, '-C', target]
567
+ when '.xz'
568
+ # NOTE: OpenBSD's tar command does not support the -J option
569
+ "#{xzcat_exe.shellescape} #{file.shellescape} | #{tar_exe.shellescape} xf - -C #{target.shellescape}"
570
+ else
571
+ [tar_exe, 'xf', file, '-C', target]
572
+ end
573
+ end
574
+
408
575
  def extract_file(file, target)
409
576
  filename = File.basename(file)
410
577
  FileUtils.mkdir_p target
411
578
 
412
579
  message "Extracting #{filename} into #{target}... "
413
- execute('extract', [tar_exe, "#{tar_compression_switch(filename)}xf", file, "-C", target], {:cd => Dir.pwd, :initial_message => false})
580
+ execute('extract', tar_command(file, target) , {:cd => Dir.pwd, :initial_message => false})
414
581
  end
415
582
 
416
583
  # command could be an array of args, or one string containing a command passed to the shell. See
@@ -420,6 +587,7 @@ private
420
587
  opt_debug = command_opts.fetch(:debug, false)
421
588
  opt_cd = command_opts.fetch(:cd) { work_path }
422
589
  opt_env = command_opts.fetch(:env) { Hash.new }
590
+ opt_altlog = command_opts.fetch(:altlog, nil)
423
591
 
424
592
  log_out = log_file(action)
425
593
 
@@ -450,12 +618,12 @@ private
450
618
  output "OK"
451
619
  return true
452
620
  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)
621
+ output "ERROR. Please review logs to see what happened:\n"
622
+ [log_out, opt_altlog].compact.each do |log|
623
+ next unless File.exist?(log)
624
+ output("----- contents of '#{log}' -----")
625
+ output(File.read(log))
626
+ output("----- end of file -----")
459
627
  end
460
628
  raise "Failed to complete #{action} task"
461
629
  end
@@ -545,7 +713,7 @@ private
545
713
  return download_file(redirect.url, full_path, count-1)
546
714
  rescue => e
547
715
  count = count - 1
548
- puts "#{count} retrie(s) left for #{filename} (#{e.message})"
716
+ @logger.puts "#{count} retrie(s) left for #{filename} (#{e.message})"
549
717
  if count > 0
550
718
  sleep 1
551
719
  return download_file_http(url, full_path, count)
@@ -604,4 +772,29 @@ private
604
772
  FileUtils.mkdir_p File.dirname(full_path)
605
773
  FileUtils.mv temp_file.path, full_path, :force => true
606
774
  end
775
+
776
+ #
777
+ # this minimal version of pkg_config is based on ruby 29dc9378 (2023-01-09)
778
+ #
779
+ # specifically with the fix from b90e56e6 to support multiple pkg-config options, and removing
780
+ # code paths that aren't helpful for mini-portile's use case of parsing pc files.
781
+ #
782
+ def minimal_pkg_config(pkg, *pcoptions)
783
+ if pcoptions.empty?
784
+ raise ArgumentError, "no pkg-config options are given"
785
+ end
786
+
787
+ if ($PKGCONFIG ||=
788
+ (pkgconfig = MakeMakefile.with_config("pkg-config") {MakeMakefile.config_string("PKG_CONFIG") || "pkg-config"}) &&
789
+ MakeMakefile.find_executable0(pkgconfig) && pkgconfig)
790
+ pkgconfig = $PKGCONFIG
791
+ else
792
+ raise RuntimeError, "pkg-config is not found"
793
+ end
794
+
795
+ pcoptions = Array(pcoptions).map { |o| "--#{o}" }
796
+ response = IO.popen([pkgconfig, *pcoptions, pkg], err:[:child, :out], &:read)
797
+ raise RuntimeError, response unless $?.success?
798
+ response.strip
799
+ end
607
800
  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
@@ -8,16 +11,14 @@ class MiniPortileCMake < MiniPortile
8
11
  def initialize(name, version, **kwargs)
9
12
  super(name, version, **kwargs)
10
13
  @cmake_command = kwargs[:cmake_command]
14
+ @cmake_build_type = kwargs[:cmake_build_type]
11
15
  end
12
16
 
13
17
  def configure_defaults
14
- if MiniPortile.mswin?
15
- ['-G', 'NMake Makefiles']
16
- elsif MiniPortile.mingw?
17
- ['-G', 'MSYS Makefiles']
18
- else
19
- []
20
- end
18
+ [
19
+ generator_defaults,
20
+ cmake_compile_flags,
21
+ ].flatten
21
22
  end
22
23
 
23
24
  def configure
@@ -48,4 +49,71 @@ class MiniPortileCMake < MiniPortile
48
49
  def cmake_cmd
49
50
  (ENV["CMAKE"] || @cmake_command || "cmake").dup
50
51
  end
52
+
53
+ def cmake_build_type
54
+ (ENV["CMAKE_BUILD_TYPE"] || @cmake_build_type || "Release").dup
55
+ end
56
+
57
+ private
58
+
59
+ def generator_defaults
60
+ if MiniPortile.mswin? && generator_available?('NMake')
61
+ ['-G', 'NMake Makefiles']
62
+ elsif MiniPortile.mingw? && generator_available?('MSYS')
63
+ ['-G', 'MSYS Makefiles']
64
+ else
65
+ []
66
+ end
67
+ end
68
+
69
+ def cmake_compile_flags
70
+ # RbConfig::CONFIG['CC'] and RbConfig::CONFIG['CXX'] can contain additional flags, for example
71
+ # "clang++ -std=gnu++11" or "clang -fdeclspec". CMake is just looking for the command name.
72
+ cc_compiler = cc_cmd.split.first
73
+ cxx_compiler = cxx_cmd.split.first
74
+
75
+ # needed to ensure cross-compilation with CMake targets the right CPU and compilers
76
+ [
77
+ "-DCMAKE_SYSTEM_NAME=#{cmake_system_name}",
78
+ "-DCMAKE_SYSTEM_PROCESSOR=#{cpu_type}",
79
+ "-DCMAKE_C_COMPILER=#{cc_compiler}",
80
+ "-DCMAKE_CXX_COMPILER=#{cxx_compiler}",
81
+ "-DCMAKE_BUILD_TYPE=#{cmake_build_type}",
82
+ ]
83
+ end
84
+
85
+ # Full list: https://gitlab.kitware.com/cmake/cmake/-/blob/v3.26.4/Modules/CMakeDetermineSystem.cmake?ref_type=tags#L12-31
86
+ def cmake_system_name
87
+ return system_name if system_name
88
+
89
+ if MiniPortile.linux?
90
+ 'Linux'
91
+ elsif MiniPortile.darwin?
92
+ 'Darwin'
93
+ elsif MiniPortile.windows?
94
+ 'Windows'
95
+ elsif MiniPortile.freebsd?
96
+ 'FreeBSD'
97
+ elsif MiniPortile.openbsd?
98
+ 'OpenBSD'
99
+ elsif MiniPortile.solaris?
100
+ 'SunOS'
101
+ else
102
+ raise "Unable to set CMAKE_SYSTEM_NAME for #{MiniPortile.target_os}"
103
+ end
104
+ end
105
+
106
+ def generator_available?(generator_type)
107
+ stdout_str, status = Open3.capture2("#{cmake_cmd} --help")
108
+
109
+ raise 'Unable to determine whether CMake supports #{generator_type} Makefile generator' unless status.success?
110
+
111
+ stdout_str.include?("#{generator_type} Makefiles")
112
+ end
113
+
114
+ def cpu_type
115
+ return 'x86_64' if MiniPortile.target_cpu == 'x64'
116
+
117
+ MiniPortile.target_cpu
118
+ end
51
119
  end
@@ -1,3 +1,3 @@
1
1
  class MiniPortile
2
- VERSION = "2.8.0"
2
+ VERSION = "2.8.9"
3
3
  end
@@ -1,7 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "mini_portile2/version"
1
+ require_relative "lib/mini_portile2/version"
5
2
 
6
3
  Gem::Specification.new do |spec|
7
4
  spec.name = "mini_portile2"
@@ -10,8 +7,12 @@ Gem::Specification.new do |spec|
10
7
  spec.authors = ["Luis Lavena", "Mike Dalessio", "Lars Kanis"]
11
8
  spec.email = "mike.dalessio@gmail.com"
12
9
 
13
- spec.summary = "Simplistic port-like solution for developers"
14
- spec.description = "Simplistic port-like solution for developers. It provides a standard and simplified way to compile against dependency libraries without messing up your system."
10
+ spec.summary = "Simple autoconf and cmake builder for developers"
11
+ spec.description = <<~TEXT
12
+ Simple autoconf and cmake builder for developers. It provides a standard way to compile against
13
+ dependency libraries without requiring system-wide installation. It also simplifies
14
+ vendoring and cross-compilation by providing a consistent build interface.
15
+ TEXT
15
16
 
16
17
  spec.homepage = "https://github.com/flavorjones/mini_portile"
17
18
  spec.licenses = ["MIT"]
@@ -33,10 +34,5 @@ Gem::Specification.new do |spec|
33
34
 
34
35
  spec.required_ruby_version = ">= 2.3.0"
35
36
 
36
- spec.add_development_dependency "bundler", "~> 2.3"
37
- spec.add_development_dependency "minitar", "~> 0.9"
38
- spec.add_development_dependency "minitest", "~> 5.15"
39
- spec.add_development_dependency "minitest-hooks", "~> 1.5"
40
- spec.add_development_dependency "rake", "~> 13.0"
41
- spec.add_development_dependency "webrick", "~> 1.7"
37
+ spec.metadata["changelog_uri"] = spec.homepage + "/blob/main/CHANGELOG.md"
42
38
  end
@@ -0,0 +1,13 @@
1
+ prefix=/foo/libxml2/2.11.5
2
+ exec_prefix=${prefix}
3
+ libdir=/foo/libxml2/2.11.5/lib
4
+ includedir=${prefix}/include
5
+ modules=1
6
+
7
+ Name: libXML
8
+ Version: 2.11.5
9
+ Description: libXML library version2.
10
+ Requires:
11
+ Libs: -L${libdir} -lxml2
12
+ Libs.private: -L/foo/zlib/1.3/lib -lz -lm
13
+ Cflags: -I${includedir}/libxml2 -ggdb3
@@ -0,0 +1,13 @@
1
+ prefix=/foo/libxslt/1.1.38
2
+ exec_prefix=${prefix}
3
+ libdir=/foo/libxslt/1.1.38/lib
4
+ includedir=${prefix}/include
5
+
6
+
7
+ Name: libexslt
8
+ Version: 0.8.21
9
+ Description: EXSLT Extension library
10
+ Requires: libxml-2.0, libxslt
11
+ Cflags: -I${includedir}
12
+ Libs: -L${libdir} -lexslt
13
+ Libs.private: -lm
@@ -0,0 +1,13 @@
1
+ prefix=/foo/libxslt/1.1.38
2
+ exec_prefix=${prefix}
3
+ libdir=/foo/libxslt/1.1.38/lib
4
+ includedir=${prefix}/include
5
+
6
+
7
+ Name: libxslt
8
+ Version: 1.1.38
9
+ Description: XSLT library version 2.
10
+ Requires: libxml-2.0
11
+ Cflags: -I${includedir} -Wno-deprecated-enum-enum-conversion
12
+ Libs: -L${libdir} -lxslt
13
+ Libs.private: -lm