mini_portile2 2.8.0 → 2.8.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +22 -5
- data/.gitignore +1 -0
- data/CHANGELOG.md +44 -0
- data/README.md +15 -2
- data/lib/mini_portile2/mini_portile.rb +205 -28
- data/lib/mini_portile2/mini_portile_cmake.rb +100 -7
- data/lib/mini_portile2/version.rb +1 -1
- data/mini_portile2.gemspec +8 -7
- 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/test_activate.rb +139 -0
- data/test/test_cmake.rb +179 -8
- data/test/test_mkmf_config.rb +202 -0
- data/test/test_recipe.rb +18 -0
- metadata +22 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f53843a25ac2651fd9970c34a44edf44de0904f99d9e63eadb3802f8dcd59bc
|
4
|
+
data.tar.gz: 075527f5c56f12de2ba5e3dfd72965a0093f62558eabb02571be5aee61cbe9f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e251640701cf8ea166e1ce6725b8e7bf3d3dbf20a659a6b90ffe127667a80f908fab5b7f816f8a766edd4166464d5375c53a3c31c862a4a7a04e0e87929127d
|
7
|
+
data.tar.gz: 1d540e216342ef799de2188935d6de440b865606a244dd7ca6a27146a259bf5a1211c53b49668eee668187770e5e030d06508b4605779c4366999dcf831cc2b3
|
data/.github/workflows/ci.yml
CHANGED
@@ -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@
|
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,15 +57,32 @@ jobs:
|
|
57
57
|
run: |
|
58
58
|
git config --system core.autocrlf false
|
59
59
|
git config --system core.eol lf
|
60
|
-
- uses: actions/checkout@
|
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@
|
67
|
+
- uses: actions/cache@v3
|
68
68
|
with:
|
69
69
|
path: examples/ports/archives
|
70
|
-
key:
|
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
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,49 @@
|
|
1
1
|
## mini_portile changelog
|
2
2
|
|
3
|
+
### 2.8.5 / 2023-10-22
|
4
|
+
|
5
|
+
#### Added
|
6
|
+
|
7
|
+
- New methods `#lib_path` and `#include_path` which point at the installed directories under `ports`. (by @flavorjones)
|
8
|
+
- Add config param for CMAKE_BUILD_TYPE, which now defaults to `Release`. (#136 by @Watson1978)
|
9
|
+
|
10
|
+
#### Experimental
|
11
|
+
|
12
|
+
Introduce experimental support for `MiniPortile#mkmf_config` which sets up MakeMakefile variables to properly link against the recipe. This should make it easier for C extensions to package third-party libraries. (by @flavorjones)
|
13
|
+
|
14
|
+
- With no arguments, will set up just `$INCFLAGS`, `$libs`, and `$LIBPATH`.
|
15
|
+
- Optionally, if provided a pkg-config file, will use that config to more precisely set `$INCFLAGS`, `$libs`, `$LIBPATH`, and `$CFLAGS`/`$CXXFLAGS`.
|
16
|
+
- Optionally, if provided the name of a static archive, will rewrite linker flags to ensure correct linkage.
|
17
|
+
|
18
|
+
Note that the behavior may change slightly before official support is announced. Please comment on [#118](https://github.com/flavorjones/mini_portile/issues/118) if you have feedback.
|
19
|
+
|
20
|
+
|
21
|
+
### 2.8.4 / 2023-07-18
|
22
|
+
|
23
|
+
- 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!)
|
24
|
+
|
25
|
+
|
26
|
+
### 2.8.3 / 2023-07-18
|
27
|
+
|
28
|
+
#### Fixed
|
29
|
+
|
30
|
+
- cmake: only use MSYS/NMake generators when available. [#129] (Thanks, @stanhu!)
|
31
|
+
|
32
|
+
|
33
|
+
### 2.8.2 / 2023-04-30
|
34
|
+
|
35
|
+
#### Fixed
|
36
|
+
|
37
|
+
- Ensure that the `source_directory` option will work when given a Windows path to an autoconf directory. [#126]
|
38
|
+
|
39
|
+
|
40
|
+
### 2.8.1 / 2022-12-24
|
41
|
+
|
42
|
+
#### Fixed
|
43
|
+
|
44
|
+
- Support applying patches via `git apply` even when the working directory resembles a git directory. [#119] (Thanks, @h0tw1r3!)
|
45
|
+
|
46
|
+
|
3
47
|
### 2.8.0 / 2022-02-20
|
4
48
|
|
5
49
|
#### Added
|
data/README.md
CHANGED
@@ -138,8 +138,8 @@ This is configurable as above, except for Windows systems where it's hardcoded t
|
|
138
138
|
The cmake command used is configurable, and in order of preference will use:
|
139
139
|
|
140
140
|
- the `CMAKE` environment variable (if present)
|
141
|
-
- the
|
142
|
-
- `"cmake"`
|
141
|
+
- the `:cmake_command` keyword argument passed into the constructor
|
142
|
+
- `"cmake"` (the default)
|
143
143
|
|
144
144
|
You can pass it in like so:
|
145
145
|
|
@@ -147,6 +147,19 @@ You can pass it in like so:
|
|
147
147
|
MiniPortileCMake.new("libfoobar", "1.3.5", cmake_command: "cmake3")
|
148
148
|
```
|
149
149
|
|
150
|
+
#### `cmake_build_type`
|
151
|
+
|
152
|
+
The cmake build type is configurable as of v2.8.5, and in order of preference will use:
|
153
|
+
|
154
|
+
- the `CMAKE_BUILD_TYPE` environment variable (if present)
|
155
|
+
- the `:cmake_build_type` keyword argument passed into the constructor
|
156
|
+
- `"Release"` (the default)
|
157
|
+
|
158
|
+
You can pass it in like so:
|
159
|
+
|
160
|
+
``` ruby
|
161
|
+
MiniPortileCMake.new("libfoobar", "1.3.5", cmake_build_type: "Debug")
|
162
|
+
```
|
150
163
|
|
151
164
|
### Local source directories
|
152
165
|
|
@@ -27,25 +27,73 @@ 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
|
|
33
|
-
attr_reader :name, :version, :original_host
|
35
|
+
attr_reader :name, :version, :original_host, :source_directory
|
34
36
|
attr_writer :configure_options
|
35
|
-
attr_accessor :host, :files, :patch_files, :target, :logger
|
37
|
+
attr_accessor :host, :files, :patch_files, :target, :logger
|
36
38
|
|
37
39
|
def self.windows?
|
38
|
-
|
40
|
+
target_os =~ /mswin|mingw/
|
39
41
|
end
|
40
42
|
|
41
43
|
# GNU MinGW compiled Ruby?
|
42
44
|
def self.mingw?
|
43
|
-
|
45
|
+
target_os =~ /mingw/
|
44
46
|
end
|
45
47
|
|
46
48
|
# MS Visual-C compiled Ruby?
|
47
49
|
def self.mswin?
|
48
|
-
|
50
|
+
target_os =~ /mswin/
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.darwin?
|
54
|
+
target_os =~ /darwin/
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.freebsd?
|
58
|
+
target_os =~ /freebsd/
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.openbsd?
|
62
|
+
target_os =~ /openbsd/
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.linux?
|
66
|
+
target_os =~ /linux/
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.solaris?
|
70
|
+
target_os =~ /solaris/
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.target_os
|
74
|
+
RbConfig::CONFIG['target_os']
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.target_cpu
|
78
|
+
RbConfig::CONFIG['target_cpu']
|
79
|
+
end
|
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
|
49
97
|
end
|
50
98
|
|
51
99
|
def initialize(name, version, **kwargs)
|
@@ -58,21 +106,21 @@ class MiniPortile
|
|
58
106
|
@logger = STDOUT
|
59
107
|
@source_directory = nil
|
60
108
|
|
61
|
-
@original_host = @host = detect_host
|
62
|
-
|
63
109
|
@gcc_command = kwargs[:gcc_command]
|
64
110
|
@make_command = kwargs[:make_command]
|
65
111
|
@open_timeout = kwargs[:open_timeout] || DEFAULT_TIMEOUT
|
66
112
|
@read_timeout = kwargs[:read_timeout] || DEFAULT_TIMEOUT
|
113
|
+
|
114
|
+
@original_host = @host = detect_host
|
67
115
|
end
|
68
116
|
|
69
117
|
def source_directory=(path)
|
70
|
-
@source_directory =
|
118
|
+
@source_directory = posix_path(path)
|
71
119
|
end
|
72
120
|
|
73
121
|
def prepare_build_directory
|
74
122
|
raise "source_directory is not set" if source_directory.nil?
|
75
|
-
output "Building #{@name}
|
123
|
+
output "Building #{@name} from source at '#{source_directory}'"
|
76
124
|
FileUtils.mkdir_p(File.join(tmp_path, [name, version].join("-")))
|
77
125
|
FileUtils.rm_rf(port_path) # make sure we always re-install
|
78
126
|
end
|
@@ -99,9 +147,9 @@ class MiniPortile
|
|
99
147
|
when which('git')
|
100
148
|
lambda { |file|
|
101
149
|
message "Running git apply with #{file}... "
|
102
|
-
|
103
|
-
|
104
|
-
|
150
|
+
Dir.mktmpdir do |tmp_git_dir|
|
151
|
+
execute('patch', ["git", "--git-dir=#{tmp_git_dir}", "--work-tree=.", "apply", "--whitespace=warn", file], :initial_message => false)
|
152
|
+
end
|
105
153
|
}
|
106
154
|
when which('patch')
|
107
155
|
lambda { |file|
|
@@ -137,7 +185,7 @@ class MiniPortile
|
|
137
185
|
# Windows doesn't recognize the shebang.
|
138
186
|
command.unshift("sh")
|
139
187
|
end
|
140
|
-
execute('configure', command + computed_options)
|
188
|
+
execute('configure', command + computed_options, altlog: "config.log")
|
141
189
|
end
|
142
190
|
|
143
191
|
def compile
|
@@ -191,19 +239,15 @@ class MiniPortile
|
|
191
239
|
end
|
192
240
|
|
193
241
|
def activate
|
194
|
-
lib_path = File.join(port_path, "lib")
|
195
242
|
vars = {
|
196
243
|
'PATH' => File.join(port_path, 'bin'),
|
197
|
-
'CPATH' =>
|
198
|
-
'LIBRARY_PATH' => lib_path
|
244
|
+
'CPATH' => include_path,
|
245
|
+
'LIBRARY_PATH' => lib_path,
|
199
246
|
}.reject { |env, path| !File.directory?(path) }
|
200
247
|
|
201
248
|
output "Activating #{@name} #{@version} (from #{port_path})..."
|
202
249
|
vars.each do |var, path|
|
203
|
-
full_path =
|
204
|
-
|
205
|
-
# turn into a valid Windows path (if required)
|
206
|
-
full_path.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
|
250
|
+
full_path = native_path(path)
|
207
251
|
|
208
252
|
# save current variable value
|
209
253
|
old_value = ENV[var] || ''
|
@@ -215,7 +259,7 @@ class MiniPortile
|
|
215
259
|
|
216
260
|
# rely on LDFLAGS when cross-compiling
|
217
261
|
if File.exist?(lib_path) && (@host != @original_host)
|
218
|
-
full_path =
|
262
|
+
full_path = native_path(lib_path)
|
219
263
|
|
220
264
|
old_value = ENV.fetch("LDFLAGS", "")
|
221
265
|
|
@@ -225,10 +269,109 @@ class MiniPortile
|
|
225
269
|
end
|
226
270
|
end
|
227
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
|
+
|
228
363
|
def path
|
229
364
|
File.expand_path(port_path)
|
230
365
|
end
|
231
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
|
+
|
232
375
|
def gcc_cmd
|
233
376
|
(ENV["CC"] || @gcc_command || RbConfig::CONFIG["CC"] || "gcc").dup
|
234
377
|
end
|
@@ -237,7 +380,15 @@ class MiniPortile
|
|
237
380
|
(ENV["MAKE"] || @make_command || ENV["make"] || "make").dup
|
238
381
|
end
|
239
382
|
|
240
|
-
private
|
383
|
+
private
|
384
|
+
|
385
|
+
def native_path(path)
|
386
|
+
MiniPortile.native_path(path)
|
387
|
+
end
|
388
|
+
|
389
|
+
def posix_path(path)
|
390
|
+
MiniPortile.posix_path(path)
|
391
|
+
end
|
241
392
|
|
242
393
|
def tmp_path
|
243
394
|
"tmp/#{@host}/ports/#{@name}/#{@version}"
|
@@ -420,6 +571,7 @@ private
|
|
420
571
|
opt_debug = command_opts.fetch(:debug, false)
|
421
572
|
opt_cd = command_opts.fetch(:cd) { work_path }
|
422
573
|
opt_env = command_opts.fetch(:env) { Hash.new }
|
574
|
+
opt_altlog = command_opts.fetch(:altlog, nil)
|
423
575
|
|
424
576
|
log_out = log_file(action)
|
425
577
|
|
@@ -450,12 +602,12 @@ private
|
|
450
602
|
output "OK"
|
451
603
|
return true
|
452
604
|
else
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
output(
|
458
|
-
output("
|
605
|
+
output "ERROR. Please review logs to see what happened:\n"
|
606
|
+
[log_out, opt_altlog].compact.each do |log|
|
607
|
+
next unless File.exist?(log)
|
608
|
+
output("----- contents of '#{log}' -----")
|
609
|
+
output(File.read(log))
|
610
|
+
output("----- end of file -----")
|
459
611
|
end
|
460
612
|
raise "Failed to complete #{action} task"
|
461
613
|
end
|
@@ -604,4 +756,29 @@ private
|
|
604
756
|
FileUtils.mkdir_p File.dirname(full_path)
|
605
757
|
FileUtils.mv temp_file.path, full_path, :force => true
|
606
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
|
607
784
|
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,96 @@ 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
|
+
c_compiler, cxx_compiler = find_c_and_cxx_compilers(host)
|
71
|
+
|
72
|
+
# needed to ensure cross-compilation with CMake targets the right CPU and compilers
|
73
|
+
[
|
74
|
+
"-DCMAKE_SYSTEM_NAME=#{cmake_system_name}",
|
75
|
+
"-DCMAKE_SYSTEM_PROCESSOR=#{cpu_type}",
|
76
|
+
"-DCMAKE_C_COMPILER=#{c_compiler}",
|
77
|
+
"-DCMAKE_CXX_COMPILER=#{cxx_compiler}",
|
78
|
+
"-DCMAKE_BUILD_TYPE=#{cmake_build_type}",
|
79
|
+
]
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_compiler(compilers)
|
83
|
+
compilers.find { |binary| which(binary) }
|
84
|
+
end
|
85
|
+
|
86
|
+
# configure automatically searches for the right compiler based on the
|
87
|
+
# `--host` parameter. However, CMake doesn't have an equivalent feature.
|
88
|
+
# Search for the right compiler for the target architecture using
|
89
|
+
# some basic heruistics.
|
90
|
+
def find_c_and_cxx_compilers(host)
|
91
|
+
c_compiler = ENV["CC"]
|
92
|
+
cxx_compiler = ENV["CXX"]
|
93
|
+
|
94
|
+
if MiniPortile.darwin?
|
95
|
+
c_compiler ||= 'clang'
|
96
|
+
cxx_compiler ||='clang++'
|
97
|
+
else
|
98
|
+
c_compiler ||= 'gcc'
|
99
|
+
cxx_compiler ||= 'g++'
|
100
|
+
end
|
101
|
+
|
102
|
+
c_platform_compiler = "#{host}-#{c_compiler}"
|
103
|
+
cxx_platform_compiler = "#{host}-#{cxx_compiler}"
|
104
|
+
c_compiler = find_compiler([c_platform_compiler, c_compiler])
|
105
|
+
cxx_compiler = find_compiler([cxx_platform_compiler, cxx_compiler])
|
106
|
+
|
107
|
+
[c_compiler, cxx_compiler]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Full list: https://gitlab.kitware.com/cmake/cmake/-/blob/v3.26.4/Modules/CMakeDetermineSystem.cmake?ref_type=tags#L12-31
|
111
|
+
def cmake_system_name
|
112
|
+
return system_name if system_name
|
113
|
+
|
114
|
+
if MiniPortile.linux?
|
115
|
+
'Linux'
|
116
|
+
elsif MiniPortile.darwin?
|
117
|
+
'Darwin'
|
118
|
+
elsif MiniPortile.windows?
|
119
|
+
'Windows'
|
120
|
+
elsif MiniPortile.freebsd?
|
121
|
+
'FreeBSD'
|
122
|
+
elsif MiniPortile.openbsd?
|
123
|
+
'OpenBSD'
|
124
|
+
elsif MiniPortile.solaris?
|
125
|
+
'SunOS'
|
126
|
+
else
|
127
|
+
raise "Unable to set CMAKE_SYSTEM_NAME for #{MiniPortile.target_os}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def generator_available?(generator_type)
|
132
|
+
stdout_str, status = Open3.capture2("#{cmake_cmd} --help")
|
133
|
+
|
134
|
+
raise 'Unable to determine whether CMake supports #{generator_type} Makefile generator' unless status.success?
|
135
|
+
|
136
|
+
stdout_str.include?("#{generator_type} Makefiles")
|
137
|
+
end
|
138
|
+
|
139
|
+
def cpu_type
|
140
|
+
return 'x86_64' if MiniPortile.target_cpu == 'x64'
|
141
|
+
|
142
|
+
MiniPortile.target_cpu
|
143
|
+
end
|
51
144
|
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,7 +34,7 @@ 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.
|
37
|
+
spec.add_development_dependency "bundler", "~> 2.2"
|
37
38
|
spec.add_development_dependency "minitar", "~> 0.9"
|
38
39
|
spec.add_development_dependency "minitest", "~> 5.15"
|
39
40
|
spec.add_development_dependency "minitest-hooks", "~> 1.5"
|
@@ -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
|