support fixing *.la

*.la files need to be fixed up in order to ensure packages link against
the right library when we try to build / install to different ROOTs.

BUG=chromium-os:11316
TEST=Compile with build_packages --nousepkg

http://codereview.chromium.org/6370011
https://gerrit.chromium.org/gerrit/42994

Change-Id: I54585ac68f5edb2a8939ec8323fe0e20bee54f69
Reviewed-on: https://chromium-review.googlesource.com/214522
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Tested-by: Bertrand Simonnet <bsimonnet@chromium.org>
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 5b947dd..764cbff 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -70,6 +70,7 @@
 from _emerge.SpawnProcess import SpawnProcess
 
 import errno
+import fileinput
 import fnmatch
 import gc
 import grp
@@ -4301,6 +4302,19 @@
 			contents=contents, env=self.settings,
 			writemsg_level=self._display_merge, vardbapi=self.vartree.dbapi)
 
+		# Fix *.la files to point to libs in target_root, if they
+		# don't do so already.
+		re_root = self.settings["ROOT"].strip("/")
+		if re_root:
+			fix_files = []
+			for path in contents:
+				if path.endswith(".la"):
+					if os.path.exists(path): fix_files.append(path)
+			if fix_files:
+				pat = re.compile(r"([' =](?:-[IL])?/)(usr|lib|opt)")
+				for line in fileinput.input(fix_files, inplace=1):
+					sys.stdout.write(pat.sub(r"\1%s/\2" % re_root, line))
+
 		# For gcc upgrades, preserved libs have to be removed after the
 		# the library path has been updated.
 		self._prune_plib_registry()
diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index 01707ae..f3d6f6d 100644
--- a/pym/portage/package/ebuild/doebuild.py
+++ b/pym/portage/package/ebuild/doebuild.py
@@ -5,6 +5,7 @@
 
 __all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild']
 
+import fileinput
 import grp
 import gzip
 import errno
@@ -1949,6 +1950,7 @@
 	destdir = mysettings["D"]
 	ed_len = len(mysettings["ED"])
 	unicode_errors = []
+	fix_files = []
 	desktop_file_validate = \
 		portage.process.find_binary("desktop-file-validate") is not None
 	xdg_dirs = mysettings.get('XDG_DATA_DIRS', '/usr/share').split(':')
@@ -2075,10 +2077,12 @@
 							new_contents, mode='wb')
 
 				mystat = os.lstat(fpath)
-				if stat.S_ISREG(mystat.st_mode) and \
-					mystat.st_ino not in counted_inodes:
-					counted_inodes.add(mystat.st_ino)
-					size += mystat.st_size
+				if stat.S_ISREG(mystat.st_mode):
+					if fname.endswith(".la"):
+						fix_files.append(fpath)
+					if mystat.st_ino not in counted_inodes:
+						counted_inodes.add(mystat.st_ino)
+						size += mystat.st_size
 				if mystat.st_uid != portage_uid and \
 					mystat.st_gid != portage_gid:
 					continue
@@ -2119,6 +2123,14 @@
 	f.write('%d\n' % size)
 	f.close()
 
+	re_root = mysettings["ROOT"].strip("/")
+	if fix_files and re_root:
+		# Replace references to our sysroot with references to "/" in binpkg.
+		# Sysroot will be re-appended when the package is installed.
+		pat = re.compile(r"([' =](-[IL])?/)%s/" % re.escape(re_root))
+		for line in fileinput.input(fix_files, inplace=1):
+			sys.stdout.write(pat.sub(r"\1", line))
+
 	_reapply_bsdflags_to_image(mysettings)
 
 def _reapply_bsdflags_to_image(mysettings):