mini_portile2 2.8.2 → 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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +101 -7
- data/.github/workflows/downstream.yml +66 -0
- data/.github/workflows/upstream.yml +39 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +66 -0
- data/Gemfile +15 -3
- data/README.md +29 -7
- data/Rakefile +3 -5
- data/lib/mini_portile2/mini_portile.rb +244 -67
- data/lib/mini_portile2/mini_portile_cmake.rb +75 -7
- data/lib/mini_portile2/version.rb +1 -1
- data/mini_portile2.gemspec +8 -12
- data/test/assets/pkgconf/libxml2/libxml-2.0.pc +13 -0
- data/test/assets/pkgconf/libxslt/libexslt.pc +13 -0
- data/test/assets/pkgconf/libxslt/libxslt.pc +13 -0
- data/test/assets/test-cmake-1.0/CMakeLists.txt +1 -1
- data/test/helper.rb +12 -1
- data/test/test_activate.rb +139 -0
- data/test/test_cmake.rb +184 -8
- data/test/test_cook.rb +30 -1
- data/test/test_digest.rb +75 -77
- data/test/test_download.rb +5 -4
- data/test/test_execute.rb +4 -3
- data/test/test_mkmf_config.rb +202 -0
- data/test/test_proxy.rb +7 -6
- data/test/test_recipe.rb +18 -0
- metadata +25 -96
@@ -5,9 +5,11 @@ require 'fileutils'
|
|
5
5
|
require 'tempfile'
|
6
6
|
require 'digest'
|
7
7
|
require 'open-uri'
|
8
|
-
require
|
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
|
39
|
+
attr_accessor :host, :files, :patch_files, :target, :logger
|
36
40
|
|
37
41
|
def self.windows?
|
38
|
-
|
42
|
+
target_os =~ /mswin|mingw/
|
39
43
|
end
|
40
44
|
|
41
45
|
# GNU MinGW compiled Ruby?
|
42
46
|
def self.mingw?
|
43
|
-
|
47
|
+
target_os =~ /mingw/
|
44
48
|
end
|
45
49
|
|
46
50
|
# MS Visual-C compiled Ruby?
|
47
51
|
def self.mswin?
|
48
|
-
|
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,15 +105,16 @@ 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
|
-
@
|
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)
|
@@ -191,11 +242,10 @@ 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' =>
|
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})..."
|
@@ -212,7 +262,7 @@ class MiniPortile
|
|
212
262
|
|
213
263
|
# rely on LDFLAGS when cross-compiling
|
214
264
|
if File.exist?(lib_path) && (@host != @original_host)
|
215
|
-
full_path =
|
265
|
+
full_path = native_path(lib_path)
|
216
266
|
|
217
267
|
old_value = ENV.fetch("LDFLAGS", "")
|
218
268
|
|
@@ -222,12 +272,114 @@ class MiniPortile
|
|
222
272
|
end
|
223
273
|
end
|
224
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
|
+
|
225
364
|
def path
|
226
365
|
File.expand_path(port_path)
|
227
366
|
end
|
228
367
|
|
229
|
-
def
|
230
|
-
(
|
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
|
231
383
|
end
|
232
384
|
|
233
385
|
def make_cmd
|
@@ -237,21 +389,11 @@ class MiniPortile
|
|
237
389
|
private
|
238
390
|
|
239
391
|
def native_path(path)
|
240
|
-
|
241
|
-
if File::ALT_SEPARATOR
|
242
|
-
path.tr(File::SEPARATOR, File::ALT_SEPARATOR)
|
243
|
-
else
|
244
|
-
path
|
245
|
-
end
|
392
|
+
MiniPortile.native_path(path)
|
246
393
|
end
|
247
394
|
|
248
395
|
def posix_path(path)
|
249
|
-
|
250
|
-
if File::ALT_SEPARATOR
|
251
|
-
"/" + path.tr(File::ALT_SEPARATOR, File::SEPARATOR).tr(":", File::SEPARATOR)
|
252
|
-
else
|
253
|
-
path
|
254
|
-
end
|
396
|
+
MiniPortile.posix_path(path)
|
255
397
|
end
|
256
398
|
|
257
399
|
def tmp_path
|
@@ -321,24 +463,29 @@ class MiniPortile
|
|
321
463
|
gpg_exe = which('gpg2') || which('gpg') || raise("Neither GPG nor GPG2 is installed")
|
322
464
|
|
323
465
|
# import the key into our own keyring
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
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
|
328
472
|
end
|
329
473
|
key_ids = gpg_status.scan(/\[GNUPG:\] IMPORT_OK \d+ (?<key_id>[0-9a-f]+)/i).map(&:first)
|
330
|
-
raise "invalid gpg key provided" if key_ids.empty?
|
474
|
+
raise "invalid gpg key provided:\n#{gpg_error}" if key_ids.empty?
|
331
475
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
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
|
339
487
|
end
|
340
488
|
|
341
|
-
raise "signature mismatch" unless gpg_status.match(/^\[GNUPG:\] VALIDSIG/)
|
342
489
|
|
343
490
|
else
|
344
491
|
digest = case
|
@@ -362,30 +509,6 @@ class MiniPortile
|
|
362
509
|
}
|
363
510
|
end
|
364
511
|
|
365
|
-
TAR_EXECUTABLES = %w[gtar bsdtar tar basic-bsdtar]
|
366
|
-
def tar_exe
|
367
|
-
@@tar_exe ||= begin
|
368
|
-
TAR_EXECUTABLES.find { |c|
|
369
|
-
which(c)
|
370
|
-
} or raise("tar not found - please make sure that one of the following commands is in the PATH: #{TAR_EXECUTABLES.join(", ")}")
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
def tar_compression_switch(filename)
|
375
|
-
case File.extname(filename)
|
376
|
-
when '.gz', '.tgz'
|
377
|
-
'z'
|
378
|
-
when '.bz2', '.tbz2'
|
379
|
-
'j'
|
380
|
-
when '.xz'
|
381
|
-
'J'
|
382
|
-
when '.Z'
|
383
|
-
'Z'
|
384
|
-
else
|
385
|
-
''
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
512
|
# From: http://stackoverflow.com/a/5471032/7672
|
390
513
|
# Thanks, Mislav!
|
391
514
|
#
|
@@ -412,6 +535,8 @@ class MiniPortile
|
|
412
535
|
output = `#{gcc_cmd} -v 2>&1`
|
413
536
|
if m = output.match(/^Target\: (.*)$/)
|
414
537
|
@detect_host = m[1]
|
538
|
+
else
|
539
|
+
@detect_host = nil
|
415
540
|
end
|
416
541
|
|
417
542
|
@detect_host
|
@@ -420,12 +545,39 @@ class MiniPortile
|
|
420
545
|
end
|
421
546
|
end
|
422
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
|
+
|
423
575
|
def extract_file(file, target)
|
424
576
|
filename = File.basename(file)
|
425
577
|
FileUtils.mkdir_p target
|
426
578
|
|
427
579
|
message "Extracting #{filename} into #{target}... "
|
428
|
-
execute('extract',
|
580
|
+
execute('extract', tar_command(file, target) , {:cd => Dir.pwd, :initial_message => false})
|
429
581
|
end
|
430
582
|
|
431
583
|
# command could be an array of args, or one string containing a command passed to the shell. See
|
@@ -561,7 +713,7 @@ class MiniPortile
|
|
561
713
|
return download_file(redirect.url, full_path, count-1)
|
562
714
|
rescue => e
|
563
715
|
count = count - 1
|
564
|
-
puts "#{count} retrie(s) left for #{filename} (#{e.message})"
|
716
|
+
@logger.puts "#{count} retrie(s) left for #{filename} (#{e.message})"
|
565
717
|
if count > 0
|
566
718
|
sleep 1
|
567
719
|
return download_file_http(url, full_path, count)
|
@@ -620,4 +772,29 @@ class MiniPortile
|
|
620
772
|
FileUtils.mkdir_p File.dirname(full_path)
|
621
773
|
FileUtils.mv temp_file.path, full_path, :force => true
|
622
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
|
623
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
data/mini_portile2.gemspec
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
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 = "
|
14
|
-
spec.description =
|
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.
|
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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# CMakeLists files in this project can
|
2
2
|
# refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and
|
3
3
|
# to the root binary directory of the project as ${HELLO_BINARY_DIR}.
|
4
|
-
cmake_minimum_required (VERSION
|
4
|
+
cmake_minimum_required (VERSION 3.5)
|
5
5
|
project (HELLO)
|
6
6
|
add_executable (hello hello.c)
|
7
7
|
install (TARGETS hello DESTINATION bin)
|
data/test/helper.rb
CHANGED
@@ -9,6 +9,12 @@ require 'archive/tar/minitar'
|
|
9
9
|
require 'fileutils'
|
10
10
|
require 'erb'
|
11
11
|
require 'mini_portile2'
|
12
|
+
require 'logger'
|
13
|
+
|
14
|
+
puts "#{__FILE__}:#{__LINE__}: relevant RbConfig::CONFIG values:"
|
15
|
+
%w[target_os target_cpu CC CXX].each do |key|
|
16
|
+
puts "- #{key}: #{RbConfig::CONFIG[key].inspect}"
|
17
|
+
end
|
12
18
|
|
13
19
|
class TestCase < Minitest::Test
|
14
20
|
include Minitest::Hooks
|
@@ -18,7 +24,12 @@ class TestCase < Minitest::Test
|
|
18
24
|
attr_accessor :webrick
|
19
25
|
|
20
26
|
def start_webrick(path)
|
21
|
-
@webrick = WEBrick::HTTPServer.new(
|
27
|
+
@webrick = WEBrick::HTTPServer.new(
|
28
|
+
:Port => HTTP_PORT,
|
29
|
+
:DocumentRoot => path,
|
30
|
+
:Logger => Logger.new(File::NULL),
|
31
|
+
:AccessLog => [],
|
32
|
+
).tap do |w|
|
22
33
|
Thread.new do
|
23
34
|
w.start
|
24
35
|
end
|