Skip to content
Browse files

Discover package dependencies from build.db during %install, make mod…

…ulemap paths absolute
  • Loading branch information...
vvmnnnkv committed Apr 26, 2019
1 parent 1e08b1d commit 0d1a84e11a6889876ca23e44886e0e9c7792e274
Showing with 40 additions and 12 deletions.
  1. +40 −12
@@ -30,6 +30,7 @@
import textwrap
import time
import threading
import sqlite3

from ipykernel.kernelbase import Kernel
from jupyter_client.jsonutil import squash_dates
@@ -591,27 +592,54 @@ def _install_packages(self, packages, swiftpm_flags):

# == Copy .swiftmodule and modulemap files to SWIFT_IMPORT_SEARCH_PATH ==

for filename in glob.glob(os.path.join(bin_dir, '*.swiftmodule')):
build_db_file = os.path.join(package_base_path, '.build', 'build.db')
if not os.path.exists(build_db_file):
raise PackageInstallException('build.db is missing')

# Toolchain root
swift_root = os.sep.join(swift_build_path.split(os.sep)[:2])
# Query to get build files list from build.db (but ignore anything from toolchain or /usr/lib)
# TODO filter out system dependencies more reliably
SELECT SUBSTR(key, 2) FROM 'key_names' WHERE key LIKE ?
AND key NOT LIKE "N{swift_root}%" AND key NOT LIKE "N/usr/lib/%"

# Connect to build.db
db_connection = sqlite3.connect(build_db_file)
cursor = db_connection.cursor()

# Process *.swiftmodules files
cursor.execute(SQL_FILES_SELECT, ['%.swiftmodule'])
swift_modules = [row[0] for row in cursor.fetchall()]
for filename in swift_modules:
shutil.copy(filename, swift_import_search_path)

# The modulemap files appear in a few different places. Add all of
# them.
# TODO: Figure out if there is a principled way to figure out where
# all the modulemap files are.
modulemap_files = glob.glob(
os.path.join(bin_dir, '**/module.modulemap'), recursive=True)
modulemap_files += glob.glob(
# Process modulemap files
cursor.execute(SQL_FILES_SELECT, ['%/module.modulemap'])
modulemap_files = [row[0] for row in cursor.fetchall()]
for index, filename in enumerate(modulemap_files):
# Create a separate directory for each modulemap file because the
# ClangImporter requires that they are all named
# "module.modulemap".
modulemap_dest = os.path.join(swift_import_search_path,
'modulemap-%d' % index)
os.makedirs(modulemap_dest, exist_ok=True)
shutil.copy(filename, modulemap_dest)
src_folder, src_filename = os.path.split(filename)
dst_path = os.path.join(modulemap_dest, src_filename)
# Make all relative header paths in module.modulemap absolute
# because we copy files to different location
with open(filename, encoding='utf8') as file:
modulemap_contents =
modulemap_contents = re.sub(
lambda m: 'header "%s"' %
( if os.path.isabs( else os.path.abspath(os.path.join(src_folder,,
outfile = open(dst_path, 'w', encoding='utf8')

# == dlopen the shared lib ==

0 comments on commit 0d1a84e

Please sign in to comment.
You can’t perform that action at this time.