1515import textwrap
1616import types
1717import json
18+ from pathlib import Path
1819
1920import package_configuration
2021
22+ def match_glob (root_dir , pattern ):
23+ return sorted ([p .relative_to (root_dir ).as_posix () for p in Path (root_dir ).glob (pattern )])
24+
2125if len (sys .argv ) == 3 :
2226 repo_dir = "external/" + sys .argv [1 ]
2327 topdir = sys .argv [2 ]
@@ -46,7 +50,9 @@ def resolve(path, pkgroot):
4650 else :
4751 return path
4852
49- def path_to_label (path , pkgroot ):
53+ symlinks = {}
54+
55+ def path_to_label (path , pkgroot , output = None ):
5056 """Substitute one pkgroot for another relative one to obtain a label."""
5157 if path .find ("${pkgroot}" ) != - 1 :
5258 # determine if the given path is inside the repository root
@@ -58,9 +64,21 @@ def path_to_label(path, pkgroot):
5864 return None if relative_path .startswith ('..' ) else relative_path .replace ('\\ ' , '/' )
5965
6066 topdir_relative_path = path .replace (os .path .realpath (pkgroot ), "$topdir" )
61- if topdir_relative_path .find ("$topdir" ) != - 1 :
67+ if topdir_relative_path .startswith ("$topdir" ):
6268 return os .path .normpath (topdir_relative_path .replace ("$topdir" , topdir )).replace ('\\ ' , '/' )
6369
70+ if not output is None :
71+ if os .path .isabs (path ) and os .path .exists (path ):
72+ global symlinks
73+ lnk = symlinks .get (path )
74+ if not lnk :
75+ lnk = "lnk_{}" .format (len (symlinks ))
76+ symlinks [path ] = lnk
77+ output .append ("#SYMLINK: {} {}" .format (path .replace ('\\ ' , '/' ), lnk ))
78+ return lnk
79+ else :
80+ print ("WARN: could not handle" , path , file = sys .stderr )
81+
6482def hs_library_pattern (name , mode = "static" , profiling = False ):
6583 """Convert hs-libraries entry to glob patterns.
6684
@@ -108,16 +126,15 @@ def hs_library_pattern(name, mode = "static", profiling = False):
108126# Accumulate package id to package name mappings.
109127pkg_id_map = []
110128
111- # pkgroot is not part of .conf files. It's a computed value. It is
112- # defined to be the directory enclosing the package database
113- # directory.
114- pkgroot = os .path .dirname (package_conf_dir )
115-
116-
117129for conf in glob .glob (os .path .join (package_conf_dir , '*.conf' )):
118130 with open (conf , 'r' ) as f :
119131 pkg = package_configuration .parse_package_configuration (f )
120132
133+ # pkgroot is not part of .conf files. It's a computed value. It is
134+ # defined to be the directory enclosing the package database
135+ # directory.
136+ pkgroot = os .path .dirname (os .path .dirname (conf ))
137+
121138 pkg_id_map .append ((pkg .name , pkg .id ))
122139
123140 # Haddock handling
@@ -201,37 +218,36 @@ def hs_library_pattern(name, mode = "static", profiling = False):
201218 name = pkg .name ,
202219 id = pkg .id ,
203220 version = pkg .version ,
204- hdrs = "glob({}, allow_empty = True)" . format ( [
205- path_to_label ( "{}/**/*.h" . format ( include_dir ) , pkgroot )
221+ hdrs = [
222+ "/" . join ([ path_to_label ( include_dir , pkgroot , output ), header ] )
206223 for include_dir in pkg .include_dirs
207- if path_to_label ( include_dir , pkgroot )
208- ]) ,
224+ for header in match_glob ( resolve ( include_dir , pkgroot ), "**/*.h" )
225+ ],
209226 includes = [
210- "/" .join ([repo_dir , path_to_label (include_dir , pkgroot )])
227+ "/" .join ([repo_dir , path_to_label (include_dir , pkgroot , output )])
211228 for include_dir in pkg .include_dirs
212- if path_to_label (include_dir , pkgroot )
213229 ],
214- static_libraries = "glob({}, allow_empty = True)" . format ( [
215- path_to_label ( "{}/{}" . format ( library_dir , pattern ), pkgroot )
230+ static_libraries = [
231+ "/" . join ([ path_to_label ( library_dir , pkgroot , output ), library ] )
216232 for hs_library in pkg .hs_libraries
217233 for pattern in hs_library_pattern (hs_library , mode = "static" , profiling = False )
218234 for library_dir in pkg .library_dirs
219- if path_to_label ( library_dir , pkgroot )
220- ]) ,
221- static_profiling_libraries = "glob({}, allow_empty = True)" . format ( [
222- path_to_label ( "{}/{}" . format ( library_dir , pattern ), pkgroot )
235+ for library in match_glob ( resolve ( library_dir , pkgroot ), pattern )
236+ ],
237+ static_profiling_libraries = [
238+ "/" . join ([ path_to_label ( library_dir , pkgroot , output ), library ] )
223239 for hs_library in pkg .hs_libraries
224240 for pattern in hs_library_pattern (hs_library , mode = "static" , profiling = True )
225241 for library_dir in pkg .library_dirs
226- if path_to_label ( library_dir , pkgroot )
227- ]) ,
228- shared_libraries = "glob({}, allow_empty = True)" . format ( [
229- path_to_label ( "{}/{}" . format ( dynamic_library_dir , pattern ), pkgroot )
242+ for library in match_glob ( resolve ( library_dir , pkgroot ), pattern )
243+ ],
244+ shared_libraries = [
245+ "/" . join ([ path_to_label ( dynamic_library_dir , pkgroot , output ), library ] )
230246 for hs_library in pkg .hs_libraries
231247 for pattern in hs_library_pattern (hs_library , mode = "dynamic" , profiling = False )
232- for dynamic_library_dir in pkg .dynamic_library_dirs + pkg .library_dirs
233- if path_to_label ( dynamic_library_dir , pkgroot )
234- ]) ,
248+ for dynamic_library_dir in set ( pkg .dynamic_library_dirs + pkg .library_dirs )
249+ for library in match_glob ( resolve ( dynamic_library_dir , pkgroot ), pattern )
250+ ],
235251 haddock_html = repr (haddock_html ),
236252 haddock_interfaces = repr (haddock_interfaces ),
237253 deps = pkg .depends ,
0 commit comments