mini_portile2 2.8.4 → 2.8.5.rc2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 999335cad76fefd8e0ec313bb0bd7260a0259ef37760a01ee34153754ea2661f
4
- data.tar.gz: 472586aad90ab8c61df7fffd60f6507206d3900fb71d505edef100ceef6e7e2f
3
+ metadata.gz: ca5eb330aa4b2b6093e3cbe77641dfd14b3eff2601dce6c97f7de69f42fffcb5
4
+ data.tar.gz: ad64c2536ab3e978c22d71bc380144f1fa579cf01993e97bf63553ec4732b851
5
5
  SHA512:
6
- metadata.gz: c978de2664efdee0bd9b89a842d33844c7ab6ee5d9dce45baaa53e061ab04777fcfb0ecc4900b772e4a2cf64c80c615b727d1227f9d09e223e30834f1dbf5ddc
7
- data.tar.gz: 58a18c5ee2c34ab370dd0d30449aa2bf06e40d7e070ab1bd5e8fcf4226e8e390516718b2b6aed0e17ee3736aa04eea45917cee53a5a1b117b78ffcb12dc4bfd3
6
+ metadata.gz: 67530e1e366cb1605a272234bbfe7ccd6d8659ebd081352a93848de694c03ad0bac23425f2a13c94f67b5c0a55273f178577f31ad088d452f4bfa810e8445c45
7
+ data.tar.gz: 47e6b00a089e83e422f51c833744226c275af1a8700a21fa11a7f81c70b952da78fbf6df3a0cd8e1347be89b8c1ce6ac0f430a6339b3d0f3340aa2fe1efa0afb
@@ -67,5 +67,22 @@ jobs:
67
67
  - uses: actions/cache@v3
68
68
  with:
69
69
  path: examples/ports/archives
70
- key: ${{ matrix.platform }}-examples-${{ hashFiles('examples/Rakefile') }}
70
+ key: examples-${{ hashFiles('examples/Rakefile') }}
71
+ - run: bundle exec rake test:examples
72
+
73
+ fedora: # see https://github.com/flavorjones/mini_portile/issues/118
74
+ runs-on: ubuntu-latest
75
+ container:
76
+ image: fedora:35
77
+ steps:
78
+ - run: |
79
+ dnf group install -y "C Development Tools and Libraries"
80
+ dnf install -y ruby ruby-devel libyaml-devel git-all patch cmake xz
81
+ - uses: actions/checkout@v3
82
+ - uses: actions/cache@v3
83
+ with:
84
+ path: examples/ports/archives
85
+ key: examples-${{ hashFiles('examples/Rakefile') }}
86
+ - run: bundle install
87
+ - run: bundle exec rake test:unit
71
88
  - run: bundle exec rake test:examples
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ Gemfile.lock
3
3
  pkg
4
4
  ports
5
5
  tmp
6
+ mkmf.log
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ## mini_portile changelog
2
2
 
3
+ ### 2.8.5.rc2 / 2023-09-17
4
+
5
+ #### Added
6
+
7
+ - New method `MiniPortile#mkmf_config` will set up MakeMakefile variables to properly link against the recipe. This should make it easier for C extensions to package third-party libraries.
8
+ - With no arguments, will set up just `$INCFLAGS`, `$libs`, and `$LIBPATH`.
9
+ - Optionally, if provided a pkg-config file, will use that config to more precisely set `$INCFLAGS`, `$libs`, `$LIBPATH`, and `$CFLAGS`/`$CXXFLAGS`.
10
+ - Optionally, if provided the name of a static archive, will rewrite linker flags to ensure correct linkage.
11
+ - New methods `#lib_path` and `#include_path` which point at the installed directories under `ports`.
12
+
13
+
3
14
  ### 2.8.4 / 2023-07-18
4
15
 
5
16
  - 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!)
@@ -27,6 +27,8 @@ class Net::HTTP
27
27
  end
28
28
  end
29
29
 
30
+ $MINI_PORTILE_STATIC_LIBS = {}
31
+
30
32
  class MiniPortile
31
33
  DEFAULT_TIMEOUT = 10
32
34
 
@@ -76,6 +78,24 @@ class MiniPortile
76
78
  RbConfig::CONFIG['target_cpu']
77
79
  end
78
80
 
81
+ def self.native_path(path)
82
+ path = File.expand_path(path)
83
+ if File::ALT_SEPARATOR
84
+ path.tr(File::SEPARATOR, File::ALT_SEPARATOR)
85
+ else
86
+ path
87
+ end
88
+ end
89
+
90
+ def self.posix_path(path)
91
+ path = File.expand_path(path)
92
+ if File::ALT_SEPARATOR
93
+ "/" + path.tr(File::ALT_SEPARATOR, File::SEPARATOR).tr(":", File::SEPARATOR)
94
+ else
95
+ path
96
+ end
97
+ end
98
+
79
99
  def initialize(name, version, **kwargs)
80
100
  @name = name
81
101
  @version = version
@@ -86,12 +106,12 @@ class MiniPortile
86
106
  @logger = STDOUT
87
107
  @source_directory = nil
88
108
 
89
- @original_host = @host = detect_host
90
-
91
109
  @gcc_command = kwargs[:gcc_command]
92
110
  @make_command = kwargs[:make_command]
93
111
  @open_timeout = kwargs[:open_timeout] || DEFAULT_TIMEOUT
94
112
  @read_timeout = kwargs[:read_timeout] || DEFAULT_TIMEOUT
113
+
114
+ @original_host = @host = detect_host
95
115
  end
96
116
 
97
117
  def source_directory=(path)
@@ -219,11 +239,10 @@ class MiniPortile
219
239
  end
220
240
 
221
241
  def activate
222
- lib_path = File.join(port_path, "lib")
223
242
  vars = {
224
243
  'PATH' => File.join(port_path, 'bin'),
225
- 'CPATH' => File.join(port_path, 'include'),
226
- 'LIBRARY_PATH' => lib_path
244
+ 'CPATH' => include_path,
245
+ 'LIBRARY_PATH' => lib_path,
227
246
  }.reject { |env, path| !File.directory?(path) }
228
247
 
229
248
  output "Activating #{@name} #{@version} (from #{port_path})..."
@@ -240,7 +259,7 @@ class MiniPortile
240
259
 
241
260
  # rely on LDFLAGS when cross-compiling
242
261
  if File.exist?(lib_path) && (@host != @original_host)
243
- full_path = File.expand_path(lib_path)
262
+ full_path = native_path(lib_path)
244
263
 
245
264
  old_value = ENV.fetch("LDFLAGS", "")
246
265
 
@@ -250,10 +269,109 @@ class MiniPortile
250
269
  end
251
270
  end
252
271
 
272
+ # pkg: the pkg-config file name (without the .pc extension)
273
+ # dir: inject the directory path for the pkg-config file (probably only useful for tests)
274
+ # static: the name of the static library archive (without the "lib" prefix or the file extension), or nil for dynamic linking
275
+ #
276
+ # we might be able to be terribly clever and infer the name of the static archive file, but
277
+ # unfortunately projects have so much freedom in what they can report (for name, for libs, etc.)
278
+ # that it feels unreliable to try to do so, so I'm preferring to just have the developer make it
279
+ # explicit.
280
+ def mkmf_config(pkg: nil, dir: nil, static: nil)
281
+ require "mkmf"
282
+
283
+ if pkg
284
+ dir ||= File.join(lib_path, "pkgconfig")
285
+ pcfile = File.join(dir, "#{pkg}.pc")
286
+ unless File.exist?(pcfile)
287
+ raise ArgumentError, "pkg-config file '#{pcfile}' does not exist"
288
+ end
289
+
290
+ output "Configuring MakeMakefile for #{File.basename(pcfile)} (in #{File.dirname(pcfile)})\n"
291
+
292
+ # on macos, pkg-config will not return --cflags without this
293
+ ENV["PKG_CONFIG_ALLOW_SYSTEM_CFLAGS"] = "t"
294
+
295
+ # append to PKG_CONFIG_PATH as we go, so later pkg-config files can depend on earlier ones
296
+ ENV["PKG_CONFIG_PATH"] = [ENV["PKG_CONFIG_PATH"], dir].compact.join(File::PATH_SEPARATOR)
297
+
298
+ incflags = minimal_pkg_config(pcfile, "cflags-only-I")
299
+ cflags = minimal_pkg_config(pcfile, "cflags-only-other")
300
+ if static
301
+ ldflags = minimal_pkg_config(pcfile, "libs-only-L", "static")
302
+ libflags = minimal_pkg_config(pcfile, "libs-only-l", "static")
303
+ else
304
+ ldflags = minimal_pkg_config(pcfile, "libs-only-L")
305
+ libflags = minimal_pkg_config(pcfile, "libs-only-l")
306
+ end
307
+ else
308
+ output "Configuring MakeMakefile for #{@name} #{@version} (from #{path})\n"
309
+
310
+ lib_name = name.sub(/\Alib/, "") # TODO: use delete_prefix when we no longer support ruby 2.4
311
+
312
+ incflags = Dir.exist?(include_path) ? "-I#{include_path}" : ""
313
+ cflags = ""
314
+ ldflags = Dir.exist?(lib_path) ? "-L#{lib_path}" : ""
315
+ libflags = Dir.exist?(lib_path) ? "-l#{lib_name}" : ""
316
+ end
317
+
318
+ if static
319
+ libdir = lib_path
320
+ if pcfile
321
+ variables = minimal_pkg_config(pcfile, "print-variables").split("\n").map(&:strip)
322
+ if variables.include?("libdir")
323
+ libdir = minimal_pkg_config(pcfile, "variable=libdir")
324
+ end
325
+ end
326
+
327
+ #
328
+ # keep track of the libraries we're statically linking against, and fix up ldflags and
329
+ # libflags to make sure we link statically against the recipe's libaries.
330
+ #
331
+ # this avoids the unintentionally dynamically linking against system libraries, and makes sure
332
+ # that if multiple pkg-config files reference each other that we are able to intercept flags
333
+ # from dependent packages that reference the static archive.
334
+ #
335
+ $MINI_PORTILE_STATIC_LIBS[static] = libdir
336
+ static_ldflags = $MINI_PORTILE_STATIC_LIBS.values.map { |v| "-L#{v}" }
337
+ static_libflags = $MINI_PORTILE_STATIC_LIBS.keys.map { |v| "-l#{v}" }
338
+
339
+ # remove `-L#{libdir}` and `-lfoo`. we don't need them since we link against the static
340
+ # archive using the full path.
341
+ ldflags = ldflags.shellsplit.reject { |f| static_ldflags.include?(f) }.shelljoin
342
+ libflags = libflags.shellsplit.reject { |f| static_libflags.include?(f) }.shelljoin
343
+
344
+ # prepend the full path to the static archive to the linker flags
345
+ static_archive = File.join(libdir, "lib#{static}.#{$LIBEXT}")
346
+ libflags = [static_archive, libflags].join(" ").strip
347
+ end
348
+
349
+ # prefer this package by prepending to search paths and library flags
350
+ #
351
+ # convert the ldflags into a list of directories and append to $LIBPATH (instead of just using
352
+ # $LDFLAGS) to ensure we get the `-Wl,-rpath` linker flag for re-finding shared libraries.
353
+ $INCFLAGS = [incflags, $INCFLAGS].join(" ").strip
354
+ libpaths = ldflags.shellsplit.map { |f| f.sub(/\A-L/, "") }
355
+ $LIBPATH = libpaths | $LIBPATH
356
+ $libs = [libflags, $libs].join(" ").strip
357
+
358
+ # prefer this package's compiler flags by appending them to the command line
359
+ $CFLAGS = [$CFLAGS, cflags].join(" ").strip
360
+ $CXXFLAGS = [$CXXFLAGS, cflags].join(" ").strip
361
+ end
362
+
253
363
  def path
254
364
  File.expand_path(port_path)
255
365
  end
256
366
 
367
+ def include_path
368
+ File.join(path, "include")
369
+ end
370
+
371
+ def lib_path
372
+ File.join(path, "lib")
373
+ end
374
+
257
375
  def gcc_cmd
258
376
  (ENV["CC"] || @gcc_command || RbConfig::CONFIG["CC"] || "gcc").dup
259
377
  end
@@ -265,21 +383,11 @@ class MiniPortile
265
383
  private
266
384
 
267
385
  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
386
+ MiniPortile.native_path(path)
274
387
  end
275
388
 
276
389
  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
390
+ MiniPortile.posix_path(path)
283
391
  end
284
392
 
285
393
  def tmp_path
@@ -648,4 +756,29 @@ class MiniPortile
648
756
  FileUtils.mkdir_p File.dirname(full_path)
649
757
  FileUtils.mv temp_file.path, full_path, :force => true
650
758
  end
759
+
760
+ #
761
+ # this minimal version of pkg_config is based on ruby 29dc9378 (2023-01-09)
762
+ #
763
+ # specifically with the fix from b90e56e6 to support multiple pkg-config options, and removing
764
+ # code paths that aren't helpful for mini-portile's use case of parsing pc files.
765
+ #
766
+ def minimal_pkg_config(pkg, *pcoptions)
767
+ if pcoptions.empty?
768
+ raise ArgumentError, "no pkg-config options are given"
769
+ end
770
+
771
+ if ($PKGCONFIG ||=
772
+ (pkgconfig = MakeMakefile.with_config("pkg-config") {MakeMakefile.config_string("PKG_CONFIG") || "pkg-config"}) &&
773
+ MakeMakefile.find_executable0(pkgconfig) && pkgconfig)
774
+ pkgconfig = $PKGCONFIG
775
+ else
776
+ raise RuntimeError, "pkg-config is not found"
777
+ end
778
+
779
+ pcoptions = Array(pcoptions).map { |o| "--#{o}" }
780
+ response = IO.popen([pkgconfig, *pcoptions, pkg], err:[:child, :out], &:read)
781
+ raise RuntimeError, response unless $?.success?
782
+ response.strip
783
+ end
651
784
  end
@@ -1,3 +1,3 @@
1
1
  class MiniPortile
2
- VERSION = "2.8.4"
2
+ VERSION = "2.8.5.rc2"
3
3
  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
@@ -0,0 +1,139 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestActivate < TestCase
4
+ attr_reader :recipe
5
+
6
+ def setup
7
+ super
8
+
9
+ @save_env = %w[PATH CPATH LIBRARY_PATH LDFLAGS].inject({}) do |env, var|
10
+ env.update(var => ENV[var])
11
+ end
12
+
13
+ FileUtils.rm_rf(["tmp", "ports"]) # remove any previous test files
14
+
15
+ @recipe = MiniPortile.new("foo", "1.0.0").tap do |recipe|
16
+ recipe.logger = StringIO.new
17
+ end
18
+ end
19
+
20
+ def teardown
21
+ FileUtils.rm_rf(["tmp", "ports"]) # remove any previous test files
22
+
23
+ @save_env.each do |var, val|
24
+ ENV[var] = val
25
+ end
26
+
27
+ super
28
+ end
29
+
30
+ def test_PATH_env_var_when_bin_does_not_exist
31
+ ENV["PATH"] = "foo"
32
+ refute(Dir.exist?(bin_path))
33
+ refute_includes(path_elements('PATH'), bin_path)
34
+
35
+ recipe.activate
36
+
37
+ refute_includes(path_elements('PATH'), bin_path)
38
+ end
39
+
40
+ def test_PATH_env_var_when_bin_exists
41
+ ENV["PATH"] = "foo"
42
+ FileUtils.mkdir_p(bin_path)
43
+ refute_includes(path_elements('PATH'), bin_path)
44
+
45
+ recipe.activate
46
+
47
+ assert_includes(path_elements('PATH'), bin_path)
48
+ assert_equal(path_elements('PATH').first, bin_path)
49
+ end
50
+
51
+ def test_CPATH_env_var_when_include_does_not_exist
52
+ ENV["CPATH"] = "foo"
53
+ refute(Dir.exist?(include_path))
54
+ refute_includes(path_elements('CPATH'), include_path)
55
+
56
+ recipe.activate
57
+
58
+ refute_includes(path_elements('CPATH'), include_path)
59
+ end
60
+
61
+ def test_CPATH_env_var_when_include_exists
62
+ ENV["CPATH"] = "foo"
63
+ FileUtils.mkdir_p(include_path)
64
+ refute_includes(path_elements('CPATH'), include_path)
65
+
66
+ recipe.activate
67
+
68
+ assert_includes(path_elements('CPATH'), include_path)
69
+ assert_equal(path_elements('CPATH').first, include_path)
70
+ end
71
+
72
+ def test_LIBRARY_PATH_env_var_when_lib_does_not_exist
73
+ ENV["LIBRARY_PATH"] = "foo"
74
+ refute(Dir.exist?(lib_path))
75
+ refute_includes(path_elements('LIBRARY_PATH'), lib_path)
76
+
77
+ recipe.activate
78
+
79
+ refute_includes(path_elements('LIBRARY_PATH'), lib_path)
80
+ end
81
+
82
+ def test_LIBRARY_PATH_env_var_when_lib_exists
83
+ ENV["LIBRARY_PATH"] = "foo"
84
+ FileUtils.mkdir_p(lib_path)
85
+ refute_includes(path_elements('LIBRARY_PATH'), lib_path)
86
+
87
+ recipe.activate
88
+
89
+ assert_includes(path_elements('LIBRARY_PATH'), lib_path)
90
+ assert_equal(path_elements('LIBRARY_PATH').first, lib_path)
91
+ end
92
+
93
+ def test_LDFLAGS_env_var_when_not_cross_compiling
94
+ ENV["LDFLAGS"] = "-lfoo"
95
+ FileUtils.mkdir_p(lib_path)
96
+ assert_equal(recipe.host, recipe.original_host) # assert on setup)
97
+
98
+ refute_includes(flag_elements('LDFLAGS'), "-L#{lib_path}")
99
+
100
+ recipe.activate
101
+
102
+ refute_includes(flag_elements('LDFLAGS'), "-L#{lib_path}")
103
+ end
104
+
105
+ def test_LDFLAGS_env_var_when_cross_compiling
106
+ ENV["LDFLAGS"] = "-lfoo"
107
+ recipe.host = recipe.original_host + "-x" # make them not-equal
108
+ FileUtils.mkdir_p(lib_path)
109
+
110
+ refute_includes(flag_elements('LDFLAGS'), "-L#{lib_path}")
111
+
112
+ recipe.activate
113
+
114
+ assert_includes(flag_elements('LDFLAGS'), "-L#{lib_path}")
115
+ assert_equal(flag_elements('LDFLAGS').first, "-L#{lib_path}")
116
+ end
117
+
118
+ private
119
+
120
+ def path_elements(varname)
121
+ ENV.fetch(varname, "").split(File::PATH_SEPARATOR)
122
+ end
123
+
124
+ def flag_elements(varname)
125
+ ENV.fetch(varname, "").split
126
+ end
127
+
128
+ def bin_path
129
+ MiniPortile.native_path(File.join(recipe.path, "bin"))
130
+ end
131
+
132
+ def include_path
133
+ MiniPortile.native_path(File.join(recipe.path, "include"))
134
+ end
135
+
136
+ def lib_path
137
+ MiniPortile.native_path(File.join(recipe.path, "lib"))
138
+ end
139
+ end
@@ -0,0 +1,202 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ require "mkmf" # initialize $LDFLAGS et al here, instead of in the middle of a test
4
+
5
+ class TestMkmfConfig < TestCase
6
+ attr_reader :recipe
7
+
8
+ LIBXML_PCP = File.join(__dir__, "assets", "pkgconf", "libxml2")
9
+ LIBXSLT_PCP = File.join(__dir__, "assets", "pkgconf", "libxslt")
10
+
11
+ def make_recipe(name, version)
12
+ MiniPortile.new(name, version).tap do |recipe|
13
+ recipe.logger = StringIO.new # hush output
14
+ end
15
+ end
16
+
17
+ def setup
18
+ super
19
+
20
+ @save_env = %w[PATH CPATH LIBRARY_PATH LDFLAGS PKG_CONFIG_PATH].inject({}) do |env, var|
21
+ env.update(var => ENV[var])
22
+ end
23
+ $INCFLAGS = "-I/xxx"
24
+ $LIBPATH = ["xxx"]
25
+ $CFLAGS = "-xxx"
26
+ $CXXFLAGS = "-xxx"
27
+ $libs = "-lxxx"
28
+ $MINI_PORTILE_STATIC_LIBS = {}
29
+
30
+ FileUtils.rm_rf(["tmp", "ports"]) # remove any previous test files
31
+
32
+ @recipe = make_recipe("libfoo", "1.0.0")
33
+ end
34
+
35
+ def teardown
36
+ FileUtils.rm_rf(["tmp", "ports"]) # remove any previous test files
37
+
38
+ $INCFLAGS = ""
39
+ $LIBPATH = []
40
+ $CFLAGS = ""
41
+ $CXXFLAGS = ""
42
+ $libs = ""
43
+ $MINI_PORTILE_STATIC_LIBS = {}
44
+ @save_env.each do |var, val|
45
+ ENV[var] = val
46
+ end
47
+
48
+ super
49
+ end
50
+
51
+ def test_mkmf_config_recipe_LIBPATH_global_lib_dir_does_not_exist
52
+ recipe.mkmf_config
53
+
54
+ refute_includes($LIBPATH, recipe.lib_path)
55
+ refute_includes($libs.shellsplit, "-lfoo")
56
+ end
57
+
58
+ def test_mkmf_config_recipe_LIBPATH_global_not_static
59
+ FileUtils.mkdir_p(recipe.lib_path)
60
+
61
+ recipe.mkmf_config
62
+
63
+ assert_includes($LIBPATH, recipe.lib_path)
64
+ assert_operator($LIBPATH.index(recipe.lib_path), :<, $LIBPATH.index("xxx")) # prepend
65
+
66
+ assert_includes($libs.shellsplit, "-lfoo") # note the recipe name is "libfoo"
67
+ assert_match(%r{-lfoo.*-lxxx}, $libs) # prepend
68
+ end
69
+
70
+ def test_mkmf_config_recipe_LIBPATH_global_static
71
+ FileUtils.mkdir_p(recipe.lib_path)
72
+ static_lib_path = File.join(recipe.lib_path, "libfoo.#{$LIBEXT}")
73
+
74
+ recipe.mkmf_config(static: "foo")
75
+
76
+ refute_includes($LIBPATH, recipe.lib_path)
77
+
78
+ refute_includes($libs.shellsplit, "-lfoo") # note the recipe name is "libfoo"
79
+ assert_includes($libs.shellsplit, static_lib_path)
80
+ assert_match(%r{#{static_lib_path}.*-lxxx}, $libs) # prepend
81
+ end
82
+
83
+ def test_mkmf_config_recipe_INCFLAGS_global_include_dir_does_not_exist
84
+ recipe.mkmf_config
85
+
86
+ refute_includes($INCFLAGS.shellsplit, "-I#{recipe.include_path}")
87
+ end
88
+
89
+ def test_mkmf_config_recipe_INCFLAGS_global
90
+ FileUtils.mkdir_p(recipe.include_path)
91
+
92
+ recipe.mkmf_config
93
+
94
+ assert_includes($INCFLAGS.shellsplit, "-I#{recipe.include_path}")
95
+ assert_match(%r{-I#{recipe.include_path}.*-I/xxx}, $INCFLAGS) # prepend
96
+ end
97
+
98
+ def test_mkmf_config_pkgconf_does_not_exist
99
+ assert_raises(ArgumentError) do
100
+ recipe.mkmf_config(pkg: "foo")
101
+ end
102
+ end
103
+
104
+ def test_mkmf_config_pkgconf_LIBPATH_global_not_static
105
+ # can't get the pkgconf utility to install on windows with ruby 2.3 in CI
106
+ skip if MiniPortile.windows? && RUBY_VERSION < "2.4"
107
+
108
+ recipe.mkmf_config(pkg: "libxml-2.0", dir: LIBXML_PCP)
109
+
110
+ assert_includes($LIBPATH, "/foo/libxml2/2.11.5/lib")
111
+ assert_operator($LIBPATH.index("/foo/libxml2/2.11.5/lib"), :<, $LIBPATH.index("xxx")) # prepend
112
+ refute_includes($LIBPATH, "/foo/zlib/1.3/lib")
113
+
114
+ assert_includes($libs.shellsplit, "-lxml2")
115
+ assert_match(%r{-lxml2.*-lxxx}, $libs) # prepend
116
+ refute_includes($libs.shellsplit, "-lz")
117
+ end
118
+
119
+ def test_mkmf_config_pkgconf_LIBPATH_global_static
120
+ # can't get the pkgconf utility to install on windows with ruby 2.3 in CI
121
+ skip if MiniPortile.windows? && RUBY_VERSION < "2.4"
122
+
123
+ static_lib_path = "/foo/libxml2/2.11.5/lib/libxml2.#{$LIBEXT}"
124
+
125
+ recipe.mkmf_config(pkg: "libxml-2.0", dir: LIBXML_PCP, static: "xml2")
126
+
127
+ refute_includes($LIBPATH, "/foo/libxml2/2.11.5/lib")
128
+ refute_includes($libs.shellsplit, "-lxml2")
129
+ assert_includes($libs.shellsplit, static_lib_path)
130
+ assert_match(%r{#{static_lib_path}.*-lxxx}, $libs) # prepend
131
+
132
+ assert_includes($LIBPATH, "/foo/zlib/1.3/lib") # from --static
133
+ assert_includes($libs.shellsplit, "-lz") # from --static
134
+ end
135
+
136
+ def test_mkmf_config_pkgconf_CFLAGS_global
137
+ # can't get the pkgconf utility to install on windows with ruby 2.3 in CI
138
+ skip if MiniPortile.windows? && RUBY_VERSION < "2.4"
139
+
140
+ recipe.mkmf_config(pkg: "libxml-2.0", dir: LIBXML_PCP)
141
+
142
+ assert_includes($INCFLAGS.shellsplit, "-I/foo/libxml2/2.11.5/include/libxml2")
143
+ assert_match(%r{-I/foo/libxml2/2.11.5/include/libxml2.*-I/xxx}, $INCFLAGS) # prepend
144
+
145
+ assert_includes($CFLAGS.shellsplit, "-ggdb3")
146
+ assert_match(%r{-xxx.*-ggdb3}, $CFLAGS) # append
147
+
148
+ assert_includes($CXXFLAGS.shellsplit, "-ggdb3")
149
+ assert_match(%r{-xxx.*-ggdb3}, $CXXFLAGS) # append
150
+ end
151
+
152
+ def test_mkmf_config_pkgconf_path_accumulation
153
+ # can't get the pkgconf utility to install on windows with ruby 2.3 in CI
154
+ skip if MiniPortile.windows? && RUBY_VERSION < "2.4"
155
+
156
+ (ENV["PKG_CONFIG_PATH"] || "").split(File::PATH_SEPARATOR).tap do |pcpaths|
157
+ refute_includes(pcpaths, LIBXML_PCP)
158
+ refute_includes(pcpaths, LIBXSLT_PCP)
159
+ end
160
+
161
+ make_recipe("libxml2", "2.11.5").tap do |recipe|
162
+ recipe.mkmf_config(pkg: "libxml-2.0", dir: LIBXML_PCP, static: "xml2")
163
+
164
+ ENV["PKG_CONFIG_PATH"].split(File::PATH_SEPARATOR).tap do |pcpaths|
165
+ assert_includes(pcpaths, LIBXML_PCP)
166
+ refute_includes(pcpaths, LIBXSLT_PCP)
167
+ end
168
+ end
169
+
170
+ make_recipe("libxslt", "1.13.8").tap do |recipe|
171
+ recipe.mkmf_config(pkg: "libxslt", dir: LIBXSLT_PCP, static: "xslt")
172
+
173
+ ENV["PKG_CONFIG_PATH"].split(File::PATH_SEPARATOR).tap do |pcpaths|
174
+ assert_includes(pcpaths, LIBXML_PCP)
175
+ assert_includes(pcpaths, LIBXSLT_PCP)
176
+ end
177
+
178
+ recipe.mkmf_config(pkg: "libexslt", dir: LIBXSLT_PCP, static: "exslt")
179
+ end
180
+
181
+ $INCFLAGS.shellsplit.tap do |incflags|
182
+ assert_includes(incflags, "-I/foo/libxml2/2.11.5/include/libxml2")
183
+ assert_includes(incflags, "-I/foo/libxslt/1.1.38/include")
184
+ end
185
+ $CFLAGS.shellsplit.tap do |cflags|
186
+ assert_includes(cflags, "-ggdb3")
187
+ assert_includes(cflags, "-Wno-deprecated-enum-enum-conversion")
188
+ end
189
+ refute_includes($LIBPATH, "/foo/libxml2/2.11.5/lib")
190
+ refute_includes($LIBPATH, "/foo/libxslt/1.1.38/lib")
191
+ assert_includes($LIBPATH, "/foo/zlib/1.3/lib") # from `--static`
192
+ $libs.shellsplit.tap do |libflags|
193
+ refute_includes(libflags, "-lxml2")
194
+ assert_includes(libflags, "/foo/libxml2/2.11.5/lib/libxml2.#{$LIBEXT}")
195
+ refute_includes(libflags, "-lxslt")
196
+ assert_includes(libflags, "/foo/libxslt/1.1.38/lib/libxslt.#{$LIBEXT}")
197
+ refute_includes(libflags, "-lexslt")
198
+ assert_includes(libflags, "/foo/libxslt/1.1.38/lib/libexslt.#{$LIBEXT}")
199
+ assert_includes(libflags, "-lz") # from `--static`
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../helper', __FILE__)
2
+
3
+ class TestRecipe < TestCase
4
+ def test_path
5
+ recipe = MiniPortile.new("libfoo", "1.0.0")
6
+ assert_equal(File.expand_path(File.join(recipe.target, recipe.host, recipe.name, recipe.version)), recipe.path)
7
+ end
8
+
9
+ def test_lib_path
10
+ recipe = MiniPortile.new("libfoo", "1.0.0")
11
+ assert_equal(File.join(recipe.path, "lib"), recipe.lib_path)
12
+ end
13
+
14
+ def test_include_path
15
+ recipe = MiniPortile.new("libfoo", "1.0.0")
16
+ assert_equal(File.join(recipe.path, "include"), recipe.include_path)
17
+ end
18
+ 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.4
4
+ version: 2.8.5.rc2
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: 2023-07-18 00:00:00.000000000 Z
13
+ date: 2023-09-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -123,17 +123,23 @@ files:
123
123
  - test/assets/gpg-fixtures/data.asc
124
124
  - test/assets/gpg-fixtures/data.invalid.asc
125
125
  - test/assets/patch 1.diff
126
+ - test/assets/pkgconf/libxml2/libxml-2.0.pc
127
+ - test/assets/pkgconf/libxslt/libexslt.pc
128
+ - test/assets/pkgconf/libxslt/libxslt.pc
126
129
  - test/assets/test mini portile-1.0.0/configure
127
130
  - test/assets/test-cmake-1.0/CMakeLists.txt
128
131
  - test/assets/test-cmake-1.0/hello.c
129
132
  - test/assets/test-download-archive.tar.gz
130
133
  - test/helper.rb
134
+ - test/test_activate.rb
131
135
  - test/test_cmake.rb
132
136
  - test/test_cook.rb
133
137
  - test/test_digest.rb
134
138
  - test/test_download.rb
135
139
  - test/test_execute.rb
140
+ - test/test_mkmf_config.rb
136
141
  - test/test_proxy.rb
142
+ - test/test_recipe.rb
137
143
  homepage: https://github.com/flavorjones/mini_portile
138
144
  licenses:
139
145
  - MIT
@@ -149,11 +155,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
149
155
  version: 2.3.0
150
156
  required_rubygems_version: !ruby/object:Gem::Requirement
151
157
  requirements:
152
- - - ">="
158
+ - - ">"
153
159
  - !ruby/object:Gem::Version
154
- version: '0'
160
+ version: 1.3.1
155
161
  requirements: []
156
- rubygems_version: 3.4.10
162
+ rubygems_version: 3.4.19
157
163
  signing_key:
158
164
  specification_version: 4
159
165
  summary: Simplistic port-like solution for developers
@@ -163,14 +169,20 @@ test_files:
163
169
  - test/assets/gpg-fixtures/data.asc
164
170
  - test/assets/gpg-fixtures/data.invalid.asc
165
171
  - test/assets/patch 1.diff
172
+ - test/assets/pkgconf/libxml2/libxml-2.0.pc
173
+ - test/assets/pkgconf/libxslt/libexslt.pc
174
+ - test/assets/pkgconf/libxslt/libxslt.pc
166
175
  - test/assets/test mini portile-1.0.0/configure
167
176
  - test/assets/test-cmake-1.0/CMakeLists.txt
168
177
  - test/assets/test-cmake-1.0/hello.c
169
178
  - test/assets/test-download-archive.tar.gz
170
179
  - test/helper.rb
180
+ - test/test_activate.rb
171
181
  - test/test_cmake.rb
172
182
  - test/test_cook.rb
173
183
  - test/test_digest.rb
174
184
  - test/test_download.rb
175
185
  - test/test_execute.rb
186
+ - test/test_mkmf_config.rb
176
187
  - test/test_proxy.rb
188
+ - test/test_recipe.rb