Skip to content
This repository has been archived by the owner on Feb 25, 2018. It is now read-only.

Commit

Permalink
implement build-time dependencies and conflict dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
rfk committed Jan 13, 2011
1 parent 76b6ffa commit b025b63
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 82 deletions.
4 changes: 2 additions & 2 deletions TODO.txt
@@ -1,3 +1,3 @@

* concept of "build deps" that are installed for building, but removed
on cleanup. Make fontconfig and freetype builddeps for wx and qt.

* settable build vars, e.g. lib_qt4.static
52 changes: 46 additions & 6 deletions myppy/envs/base.py
Expand Up @@ -107,14 +107,18 @@ def SITE_PACKAGES(self):
def init(self):
"""Build the base myppy python environment."""
for dep in self.DEPENDENCIES:
self.install(dep,initialising=True)
self.install(dep,initialising=True,explicit=False)

def clean(self):
"""Clean out temporary built files and the like."""
if os.path.exists(self.builddir):
shutil.rmtree(self.builddir)
if os.path.exists(self.cachedir):
shutil.rmtree(self.cachedir)
q = "SELECT DISTINCT recipe FROM installed_files"
for row in self._db.execute(q):
if not self.is_explicitly_installed(row[0]):
self.uninstall(row[0])
for fpath in self.find_new_files():
if os.path.isfile(fpath) or os.path.islink(fpath):
os.unlink(fpath)
Expand All @@ -126,6 +130,9 @@ def do(self,*cmdline,**kwds):
stdin = kwds.pop("stdin",None)
if stdin is None:
stdin = sys.stdin
for (k,v) in env.iteritems():
if not isinstance(v,basestring):
raise ValueError("NONSTRING %r => %r " % (k,v,))
subprocess.check_call(cmdline,env=env,stdin=stdin,**kwds)

def bt(self,*cmdline,**kwds):
Expand Down Expand Up @@ -154,19 +161,41 @@ def is_initialised(self):
return True

def is_installed(self,recipe):
q = "SELECT filepath FROM installed_files WHERE recipe=?"\
" LIMIT 1"
q = "SELECT filepath FROM installed_files WHERE recipe=? LIMIT 1"
return (self._db.execute(q,(recipe,)).fetchone() is not None)

def is_explicitly_installed(self,recipe):
deps = set(self.DEPENDENCIES)
for row in self._db.execute("SELECT recipe FROM installed_recipes"):
deps.add(row[0])
todo = list(deps)
while todo:
r = self.load_recipe(todo.pop(0))
for dep in r.DEPENDENCIES:
if dep not in deps:
deps.add(dep)
todo.append(dep)
return recipe in deps

def install(self,recipe,initialising=False):
def install(self,recipe,initialising=False,explicit=True):
"""Install the named recipe into this myppy env."""
if not self.is_installed(recipe):
r = self.load_recipe(recipe)
if not initialising and not self.is_initialised():
self.init()
for conflict in r.CONFLICTS_WITH:
if self.is_explicitly_installed(conflict):
msg = "Recipe %r conflicts with %r, "
msg += "which is already installed"
msg %= (recipe,conflict,)
raise RuntimeError(msg)
self.uninstall(conflict)
for dep in r.DEPENDENCIES:
if dep != recipe:
self.install(dep,initialising=initialising)
self.install(dep,initialising=initialising,explicit=False)
for dep in r.BUILD_DEPENDENCIES:
if dep != recipe:
self.install(dep,initialising=initialising,explicit=False)
print "FETCHING", recipe
r.fetch()
with self:
Expand All @@ -178,18 +207,26 @@ def install(self,recipe,initialising=False):
files = list(self.find_new_files())
self.record_files(recipe,files)
print "INSTALLED", recipe
if explicit and not self.is_explicitly_installed(recipe):
q = "INSERT INTO installed_recipes VALUES (?)"
self._db.execute(q,(recipe,))

def uninstall(self,recipe):
"""Uninstall the named recipe from this myppy env."""
# TODO: remove things depending on it
with self:
q = "DELETE FROM installed_recipes WHERE recipe=?"
self._db.execute(q,(recipe,))
q = "SELECT filepath FROM installed_files WHERE recipe=?"\
" ORDER BY filepath DESC"
files = [r[0] for r in self._db.execute(q,(recipe,))]
q = "DELETE FROM installed_files WHERE recipe=?"
self._db.execute(q,(recipe,))
for file in files:
assert util.relpath(file) == file
if self._old_files_cache is not None:
self._old_files_cache.remove(file)
for file in files:
filepath = os.path.join(self.rootdir,file)
if not os.path.exists(filepath):
continue
Expand Down Expand Up @@ -238,7 +275,6 @@ def _is_oldfile(self,file):
self._old_files_cache = set()
for r in self._db.execute("SELECT filepath FROM installed_files"):
self._old_files_cache.add(r[0])
q = "SELECT * FROM installed_files WHERE filepath=?"
file = file[len(self.rootdir)+1:]
assert util.relpath(file) == file
if file in self._old_files_cache:
Expand Down Expand Up @@ -278,6 +314,7 @@ def find_new_files(self):
yield fpath

def record_files(self,recipe,files):
"""Record the given list of files as installed for the given recipe."""
files = list(files)
assert files, "recipe '%s' didn't install any files" % (recipe,)
for file in files:
Expand All @@ -289,6 +326,9 @@ def record_files(self,recipe,files):
self._old_files_cache.add(file)

def _initdb(self):
self._db.execute("CREATE TABLE IF NOT EXISTS installed_recipes ("
" recipe STRING NOT NULL"
")")
self._db.execute("CREATE TABLE IF NOT EXISTS installed_files ("
" recipe STRING NOT NULL,"
" filepath STRING NOT NULL"
Expand Down
11 changes: 9 additions & 2 deletions myppy/envs/linux.py
Expand Up @@ -4,6 +4,7 @@
from __future__ import with_statement

import os
import stat

from myppy.envs import base

Expand Down Expand Up @@ -34,15 +35,21 @@ def record_files(self,recipe,files):
if recipe not in self._RECIPES_WITH_APGCC_PROBLEMS:
if fnm.endswith(".so") or ".so." in fnm:
self._check_glibc_symbols(fpath)
self.do("strip",fpath)
self._strip(fpath)
self._adjust_rpath(fpath)
elif "." not in fnm:
fileinfo = self.bt("file",fpath)
if "executable" in fileinfo and "ELF" in fileinfo:
self.do("strip",fpath)
self._strip(fpath)
self._adjust_rpath(fpath)
super(MyppyEnv,self).record_files(recipe,files)

def _strip(self,fpath):
mod = os.stat(fpath).st_mode
os.chmod(fpath,stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
self.do("strip",fpath)
os.chmod(fpath,mod)

def _check_glibc_symbols(self,fpath):
print "VERIFYING GLIBC SYMBOLS", fpath
for ln in self.bt("objdump","-T",fpath).split("\n"):
Expand Down
6 changes: 6 additions & 0 deletions myppy/envs/macosx.py
Expand Up @@ -75,6 +75,12 @@ def _adjust_static_lib(self,recipe,fpath):
self._check_lib_has_all_archs(fpath)

def _adjust_dynamic_lib(self,recipe,fpath):
mod = os.stat(fpath).st_mode
try:
os.chmod(fpath,0x700)
self.do("strip",fpath)
finally:
os.chmod(fpath,mod)
self._check_lib_has_all_archs(fpath)
self._check_lib_uses_correct_sdk(fpath)
self._adjust_linker_paths(fpath)
Expand Down

0 comments on commit b025b63

Please sign in to comment.