@@ -1198,48 +1198,56 @@ def _build_tarball(
11981198 ):
11991199 raise NoOverwriteException (url_util .format (remote_specfile_path ))
12001200
1201- # make a copy of the install directory to work with
1202- workdir = os .path .join (tmpdir , os .path .basename (spec .prefix ))
1203- # install_tree copies hardlinks
1204- # create a temporary tarfile from prefix and exract it to workdir
1205- # tarfile preserves hardlinks
1206- temp_tarfile_name = tarball_name (spec , ".tar" )
1207- temp_tarfile_path = os .path .join (tarfile_dir , temp_tarfile_name )
1208- with closing (tarfile .open (temp_tarfile_path , "w" )) as tar :
1209- tar .add (name = "%s" % spec .prefix , arcname = "." )
1210- with closing (tarfile .open (temp_tarfile_path , "r" )) as tar :
1211- tar .extractall (workdir )
1212- os .remove (temp_tarfile_path )
1201+ pkg_dir = os .path .basename (spec .prefix .rstrip (os .path .sep ))
1202+ workdir = os .path .join (tmpdir , pkg_dir )
1203+
1204+ # TODO: We generally don't want to mutate any files, but when using relative
1205+ # mode, Spack unfortunately *does* mutate rpaths and links ahead of time.
1206+ # For now, we only make a full copy of the spec prefix when in relative mode.
1207+
1208+ if relative :
1209+ # tarfile is used because it preserves hardlink etc best.
1210+ binaries_dir = workdir
1211+ temp_tarfile_name = tarball_name (spec , ".tar" )
1212+ temp_tarfile_path = os .path .join (tarfile_dir , temp_tarfile_name )
1213+ with closing (tarfile .open (temp_tarfile_path , "w" )) as tar :
1214+ tar .add (name = "%s" % spec .prefix , arcname = "." )
1215+ with closing (tarfile .open (temp_tarfile_path , "r" )) as tar :
1216+ tar .extractall (workdir )
1217+ os .remove (temp_tarfile_path )
1218+ else :
1219+ binaries_dir = spec .prefix
1220+ mkdirp (os .path .join (workdir , ".spack" ))
12131221
12141222 # create info for later relocation and create tar
12151223 write_buildinfo_file (spec , workdir , relative )
12161224
12171225 # optionally make the paths in the binaries relative to each other
12181226 # in the spack install tree before creating tarball
1219- if relative :
1220- try :
1227+ try :
1228+ if relative :
12211229 make_package_relative (workdir , spec , allow_root )
1222- except Exception as e :
1223- shutil .rmtree (workdir )
1224- shutil .rmtree (tarfile_dir )
1225- shutil .rmtree (tmpdir )
1226- tty .die (e )
1227- else :
1228- try :
1229- check_package_relocatable (workdir , spec , allow_root )
1230- except Exception as e :
1231- shutil .rmtree (workdir )
1232- shutil .rmtree (tarfile_dir )
1233- shutil .rmtree (tmpdir )
1234- tty .die (e )
1230+ elif not allow_root :
1231+ ensure_package_relocatable (workdir , binaries_dir )
1232+ except Exception as e :
1233+ shutil .rmtree (workdir )
1234+ shutil .rmtree (tarfile_dir )
1235+ shutil .rmtree (tmpdir )
1236+ tty .die (e )
12351237
12361238 # create gzip compressed tarball of the install prefix
12371239 # On AMD Ryzen 3700X and an SSD disk, we have the following on compression speed:
12381240 # compresslevel=6 gzip default: llvm takes 4mins, roughly 2.1GB
12391241 # compresslevel=9 python default: llvm takes 12mins, roughly 2.1GB
12401242 # So we follow gzip.
12411243 with closing (tarfile .open (tarfile_path , "w:gz" , compresslevel = 6 )) as tar :
1242- tar .add (name = "%s" % workdir , arcname = "%s" % os .path .basename (spec .prefix ))
1244+ tar .add (name = binaries_dir , arcname = pkg_dir )
1245+ if not relative :
1246+ # Add buildinfo file
1247+ buildinfo_path = buildinfo_file_name (workdir )
1248+ buildinfo_arcname = buildinfo_file_name (pkg_dir )
1249+ tar .add (name = buildinfo_path , arcname = buildinfo_arcname )
1250+
12431251 # remove copy of install directory
12441252 shutil .rmtree (workdir )
12451253
@@ -1567,16 +1575,11 @@ def make_package_relative(workdir, spec, allow_root):
15671575 relocate .make_link_relative (cur_path_names , orig_path_names )
15681576
15691577
1570- def check_package_relocatable (workdir , spec , allow_root ):
1571- """
1572- Check if package binaries are relocatable.
1573- Change links to placeholder links.
1574- """
1578+ def ensure_package_relocatable (workdir , binaries_dir ):
1579+ """Check if package binaries are relocatable."""
15751580 buildinfo = read_buildinfo_file (workdir )
1576- cur_path_names = list ()
1577- for filename in buildinfo ["relocate_binaries" ]:
1578- cur_path_names .append (os .path .join (workdir , filename ))
1579- allow_root or relocate .ensure_binaries_are_relocatable (cur_path_names )
1581+ binaries = [os .path .join (binaries_dir , f ) for f in buildinfo ["relocate_binaries" ]]
1582+ relocate .ensure_binaries_are_relocatable (binaries )
15801583
15811584
15821585def dedupe_hardlinks_if_necessary (root , buildinfo ):
0 commit comments