Class: Rubycc::Pkgconf::Resolver
- Inherits:
-
Object
- Object
- Rubycc::Pkgconf::Resolver
- Defined in:
- lib/rubycc/pkgconf/resolver.rb
Overview
Loads .pc files by name from a search path and walks their Requires chain to produce the token lists --cflags/--libs need. A module is loaded at most once per Resolver (a memoizing cache doubling as the cycle guard for a Requires loop); within a single module's own Cflags/Libs value, tokens are kept exactly as written — no de-duplication is attempted (see the Step 59 report: this cannot be measured against the real pkg-config in this environment, so the simplest order-preserving concatenation is used, which is all mkmf's pkg_config() needs).
Instance Method Summary collapse
-
#cflags_tokens(name, visited = {}) ⇒ Object
Own Cflags, then each public Requires recursively, then each Requires.private recursively — a private dependency's compiler flags are still needed to build against
name, they are just not exposed to its dependents (that asymmetry is Requires.private's whole point). -
#exists?(name) ⇒ Boolean
True if
nameand its whole Requires/Requires.private chain resolve — the same thingpkg-config --existshas to check, since it must load every dependency's .pc file to answer the question. -
#initialize(directories: SearchPath.directories) ⇒ Resolver
constructor
A new instance of Resolver.
-
#libs_tokens(name, visited = {}) ⇒ Object
Own Libs, then each public Requires recursively.
- #load(name) ⇒ Object
Constructor Details
#initialize(directories: SearchPath.directories) ⇒ Resolver
Returns a new instance of Resolver.
16 17 18 19 |
# File 'lib/rubycc/pkgconf/resolver.rb', line 16 def initialize(directories: SearchPath.directories) @directories = directories @cache = {} end |
Instance Method Details
#cflags_tokens(name, visited = {}) ⇒ Object
Own Cflags, then each public Requires recursively, then each
Requires.private recursively — a private dependency's compiler flags
are still needed to build against name, they are just not exposed to
its dependents (that asymmetry is Requires.private's whole point).
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/rubycc/pkgconf/resolver.rb', line 44 def cflags_tokens(name, visited = {}) return [] if visited[name] visited[name] = true pkg = load(name) tokens = Shellwords.split(pkg.cflags) pkg.requires.each { |dep| tokens.concat(cflags_tokens(dep, visited)) } pkg.requires_private.each { |dep| tokens.concat(cflags_tokens(dep, visited)) } tokens end |
#exists?(name) ⇒ Boolean
True if name and its whole Requires/Requires.private chain resolve —
the same thing pkg-config --exists has to check, since it must load
every dependency's .pc file to answer the question.
24 25 26 27 28 29 |
# File 'lib/rubycc/pkgconf/resolver.rb', line 24 def exists?(name) cflags_tokens(name) true rescue PkgconfError false end |
#libs_tokens(name, visited = {}) ⇒ Object
Own Libs, then each public Requires recursively. Requires.private never contributes here — pkg-config only pulls a private dependency's Libs into the static-link case (Libs.private via --static), which mkmf's pkg_config() never requests, so it is out of scope.
59 60 61 62 63 64 65 66 67 |
# File 'lib/rubycc/pkgconf/resolver.rb', line 59 def libs_tokens(name, visited = {}) return [] if visited[name] visited[name] = true pkg = load(name) tokens = Shellwords.split(pkg.libs) pkg.requires.each { |dep| tokens.concat(libs_tokens(dep, visited)) } tokens end |
#load(name) ⇒ Object
31 32 33 34 35 36 37 38 |
# File 'lib/rubycc/pkgconf/resolver.rb', line 31 def load(name) return @cache[name] if @cache.key?(name) path = SearchPath.find(name, directories: @directories) raise NotFoundError, "package '#{name}' not found (searched #{@directories.join(File::PATH_SEPARATOR)})" unless path @cache[name] = Parser.parse(File.read(path), path: path) end |