123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- import sys
- import os
- REMOVE_THESE = ["-I/usr/include", "-I/usr/include/", "-L/usr/lib", "-L/usr/lib/"]
- class Pkg:
- def __init__(self, pkg_name):
- self.name = pkg_name
- self.priority = 0
- self.vars = {}
- def parse(self, pkg_config_path):
- f = None
- for pkg_path in pkg_config_path.split(':'):
- if pkg_path[-1] != '/':
- pkg_path += '/'
- fname = pkg_path + self.name + '.pc'
- try:
- f = open(fname, "r")
- break
- except:
- continue
- if not f:
- #sys.stderr.write("pkgconfig.py: unable to find %s.pc in %s\n" % (self.name, pkg_config_path))
- return False
- for line in f.readlines():
- line = line.strip()
- if not line:
- continue
- if line[0]=='#':
- continue
- pos1 = line.find('=')
- pos2 = line.find(':')
- if pos1 > 0 and (pos1 < pos2 or pos2 < 0):
- pos = pos1
- elif pos2 > 0 and (pos2 < pos1 or pos1 < 0):
- pos = pos2
- else:
- continue
- name = line[:pos].lower()
- value = line[pos+1:]
- self.vars[name] = value
- f.close()
- for name in self.vars.keys():
- value = self.vars[name]
- while True:
- pos1 = value.find("${")
- if pos1 < 0:
- break
- pos2 = value.find("}")
- if pos2 < 0:
- break
- value = value.replace(value[pos1:pos2+1], self.vars[value[pos1+2:pos2]])
- self.vars[name] = value
- return True
- def requires(self):
- if not 'requires' in self.vars:
- return []
- deps = []
- req_list = self.vars['requires']
- for req_item in req_list.split(','):
- req_item = req_item.strip()
- for i in range(len(req_item)):
- if "=<>".find(req_item[i]) >= 0:
- deps.append(req_item[:i].strip())
- break
- return deps
- def libs(self):
- if not 'libs' in self.vars:
- return []
- return self.vars['libs'].split(' ')
- def cflags(self):
- if not 'cflags' in self.vars:
- return []
- return self.vars['cflags'].split(' ')
- def calculate_pkg_priority(pkg, pkg_dict, loop_cnt):
- if loop_cnt > 10:
- sys.stderr.write("Circular dependency with pkg %s\n" % (pkg))
- return 0
- reqs = pkg.requires()
- prio = 1
- for req in reqs:
- if not req in pkg_dict:
- continue
- req_pkg = pkg_dict[req]
- prio += calculate_pkg_priority(req_pkg, pkg_dict, loop_cnt+1)
- return prio
- if __name__ == "__main__":
- pkg_names = []
- pkg_dict = {}
- commands = []
- exist_check = False
- for i in range(1,len(sys.argv)):
- if sys.argv[i][0] == '-':
- cmd = sys.argv[i]
- commands.append(cmd)
- if cmd=='--exists':
- exist_check = True
- elif cmd=="--help":
- print("This is not very helpful, is it")
- sys.exit(0)
- elif cmd=="--version":
- print("0.1")
- sys.exit(0)
- else:
- pkg_names.append(sys.argv[i])
-
- # Fix search path
- PKG_CONFIG_PATH = os.getenv("PKG_CONFIG_PATH", "").strip()
- if not PKG_CONFIG_PATH:
- PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:/usr/lib/pkgconfig"
- PKG_CONFIG_PATH = PKG_CONFIG_PATH.replace(";", ":")
- # Parse files
- for pkg_name in pkg_names:
- pkg = Pkg(pkg_name)
- if not pkg.parse(PKG_CONFIG_PATH):
- sys.exit(1)
- pkg_dict[pkg_name] = pkg
- if exist_check:
- sys.exit(0)
- # Calculate priority based on dependency
- for pkg_name in pkg_dict.keys():
- pkg = pkg_dict[pkg_name]
- pkg.priority = calculate_pkg_priority(pkg, pkg_dict, 1)
-
- # Sort package based on dependency
- pkg_names = sorted(pkg_names, key=lambda pkg_name: pkg_dict[pkg_name].priority, reverse=True)
- # Get the options
- opts = []
- for cmd in commands:
- if cmd=='--libs':
- for pkg_name in pkg_names:
- libs = pkg_dict[pkg_name].libs()
- for lib in libs:
- opts.append(lib)
- if lib[:2]=="-l":
- break
- for pkg_name in pkg_names:
- opts += pkg_dict[pkg_name].libs()
- elif cmd=='--cflags':
- for pkg_name in pkg_names:
- opts += pkg_dict[pkg_name].cflags()
- elif cmd[0]=='-':
- sys.stderr.write("pkgconfig.py: I don't know how to handle " + sys.argv[i] + "\n")
-
- filtered_opts = []
- for opt in opts:
- opt = opt.strip()
- if not opt:
- continue
- if REMOVE_THESE.count(opt) != 0:
- continue
- if opt != '-framework' and opt != '--framework' and filtered_opts.count(opt) != 0:
- if len(filtered_opts) and (filtered_opts[-1] == '-framework' or filtered_opts[-1] == '--framework'):
- filtered_opts.pop()
- continue
- filtered_opts.append(opt)
- print(' '.join(filtered_opts))
|