[Git][ghc/ghc][wip/hadrian-windows-bindist] 3 commits: hadrian: Add reloc-binary-dist-* targets

Matthew Pickering (@mpickering) gitlab at gitlab.haskell.org
Thu Aug 17 10:52:44 UTC 2023



Matthew Pickering pushed to branch wip/hadrian-windows-bindist at Glasgow Haskell Compiler / GHC


Commits:
9d615027 by Matthew Pickering at 2023-08-17T11:52:24+01:00
hadrian: Add reloc-binary-dist-* targets

This adds a command line option to build a "relocatable" bindist.

The bindist is created by first creating a normal bindist and then
installing it using the `RelocatableBuild=YES` option. This creates a
bindist without any wrapper scripts pointing to the libdir.

The motivation for this feature is that we want to ship relocatable
bindists on windows and this method is more uniform than the ad-hoc
method which lead to bugs such as #23608 and #23476

The relocatable bindist can be built with the "reloc-binary-dist" target
and supports the same suffixes as the normal "binary-dist" command to
specify the compression style.

- - - - -
73c3837d by Matthew Pickering at 2023-08-17T11:52:31+01:00
packaging: Fix installation scripts on windows/RelocatableBuild case

This includes quite a lot of small fixes which fix the installation
makefile to work on windows properly. This also required fixing the
RelocatableBuild variable which seemed to have been broken for a long
while.

Sam helped me a lot writing this patch by providing a windows machine to
test the changes. Without him it would have taken ages to tweak
everything.

Co-authored-by: sheaf <sam.derbyshire at gmail.com>

- - - - -
40074cf9 by Matthew Pickering at 2023-08-17T11:52:31+01:00
ci: Build relocatable bindist on windows

We now build the relocatable bindist target on windows, which means we
test and distribute the new method of creating a relocatable bindist.

- - - - -


6 changed files:

- .gitlab/ci.sh
- distrib/configure.ac.in
- hadrian/README.md
- hadrian/bindist/Makefile
- hadrian/bindist/config.mk.in
- hadrian/src/Rules/BinaryDist.hs


Changes:

=====================================
.gitlab/ci.sh
=====================================
@@ -490,8 +490,16 @@ function build_hadrian() {
   if [[ -n "${REINSTALL_GHC:-}" ]]; then
     run_hadrian build-cabal -V
   else
-    run_hadrian test:all_deps binary-dist -V
-    mv _build/bindist/ghc*.tar.xz "$BIN_DIST_NAME.tar.xz"
+    case "$(uname)" in
+        MSYS_*|MINGW*)
+          run_hadrian test:all_deps reloc-binary-dist -V
+          mv _build/reloc-bindist/ghc*.tar.xz "$BIN_DIST_NAME.tar.xz"
+          ;;
+        *)
+          run_hadrian test:all_deps binary-dist -V
+          mv _build/bindist/ghc*.tar.xz "$BIN_DIST_NAME.tar.xz"
+          ;;
+    esac
   fi
 
 }


=====================================
distrib/configure.ac.in
=====================================
@@ -103,6 +103,17 @@ AC_ARG_ENABLE(distro-toolchain,
   [EnableDistroToolchain=@SettingsUseDistroMINGW@]
 )
 
+if test "$HostOS" = "mingw32" -a "$EnableDistroToolchain" = "NO"; then
+  FP_SETUP_WINDOWS_TOOLCHAIN([$hardtop/mingw/], [\$\$topdir/../mingw/])
+fi
+
+if test "$HostOS" = "mingw32"; then
+    WindresCmd="$Windres"
+    AC_SUBST([WindresCmd])
+    AC_SUBST([GenlibCmd])
+    AC_SUBST([HAVE_GENLIB])
+fi
+
 dnl ** Which gcc to use?
 dnl --------------------------------------------------------------
 AC_PROG_CC([gcc clang])
@@ -288,6 +299,7 @@ if test "x$UseLibdw" = "xYES" ; then
 fi
 AC_SUBST(UseLibdw)
 
+
 FP_SETTINGS
 
 AC_CONFIG_FILES([config.mk])


=====================================
hadrian/README.md
=====================================
@@ -325,6 +325,13 @@ $ ./configure [--prefix=PATH] && make install
 
 workflow, for now.
 
+Note: On windows you need to use the `reloc-binary-dist` target.
+
+#### Relocatable Binary Distribution
+
+If you require a relocatable binary distribution (for example on Windows), then you
+can build the `reloc-binary-dist` target.
+
 ### Building and installing GHC
 
 You can get Hadrian to build _and_ install a binary distribution in one go


=====================================
hadrian/bindist/Makefile
=====================================
@@ -63,19 +63,28 @@ show:
 .PHONY: install
 
 ifeq "$(TargetOS_CPP)" "mingw32"
-install_bin: install_mingw install_bin_direct
+install_extra: install_mingw
+else
+install_extra:
+endif
+
+ifeq "$(RelocatableBuild)" "YES"
+install_bin: install_bin_direct
 else
 install_bin: install_bin_libdir install_wrappers
 endif
 
-install: install_bin install_lib
+
+
+install: install_bin install_lib install_extra
 install: install_man install_docs update_package_db
 
-ActualBinsDir=${ghclibdir}/bin
 ifeq "$(RelocatableBuild)" "YES"
 ActualLibsDir=${ghclibdir}
+ActualBinsDir=${bindir}
 else
 ActualLibsDir=${ghclibdir}/lib
+ActualBinsDir=${ghclibdir}/bin
 endif
 WrapperBinsDir=${bindir}
 


=====================================
hadrian/bindist/config.mk.in
=====================================
@@ -67,6 +67,12 @@ $(eval $(call set_default,dvidir,$${docdir}))
 $(eval $(call set_default,pdfdir,$${docdir}))
 $(eval $(call set_default,psdir,$${docdir}))
 
+# On Windows we normally want to make a relocatable bindist, to we
+# ignore flags like libdir
+ifeq "$(Windows_Host)" "YES"
+RelocatableBuild = YES
+endif
+
 ifeq "$(RelocatableBuild)" "YES"
 
 # Hack: our directory layouts tend to be different on Windows, so
@@ -153,14 +159,6 @@ else
 GhcWithInterpreter=$(if $(findstring YES,$(DYNAMIC_GHC_PROGRAMS)),YES,NO)
 endif
 
-# On Windows we normally want to make a relocatable bindist, to we
-# ignore flags like libdir
-ifeq "$(Windows_Host)" "YES"
-RelocatableBuild = YES
-else
-RelocatableBuild = NO
-endif
-
 
 
 ifneq "$(DESTDIR)" ""


=====================================
hadrian/src/Rules/BinaryDist.hs
=====================================
@@ -110,20 +110,40 @@ other, the install script:
 
 -}
 
+data Relocatable = Relocatable | NotRelocatable
+
+installTo :: Relocatable -> String -> Action ()
+installTo relocatable prefix = do
+    root <- buildRoot
+    version        <- setting ProjectVersion
+    targetPlatform <- setting TargetPlatformFull
+    let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
+        bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
+    runBuilder (Configure bindistFilesDir) ["--prefix="++prefix] [] []
+    let env = case relocatable of
+                Relocatable -> [AddEnv "RelocatableBuild" "YES"]
+                NotRelocatable -> []
+    runBuilderWithCmdOptions env (Make bindistFilesDir) ["install"] [] []
+
 bindistRules :: Rules ()
 bindistRules = do
     root <- buildRootRules
-    phony "install" $ do
+    phony "reloc-binary-dist-dir" $ do
         need ["binary-dist-dir"]
+        cwd <- liftIO $ IO.getCurrentDirectory
         version        <- setting ProjectVersion
         targetPlatform <- setting TargetPlatformFull
         let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
-            bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
-            prefixErr = "You must specify a path with --prefix when using the"
+        let prefix = cwd -/- root -/- "reloc-bindist" -/- ghcVersionPretty
+        installTo Relocatable prefix
+
+
+    phony "install" $ do
+        need ["binary-dist-dir"]
+        let prefixErr = "You must specify a path with --prefix when using the"
                      ++ " 'install' rule"
         installPrefix <- fromMaybe (error prefixErr) <$> cmdPrefix
-        runBuilder (Configure bindistFilesDir) ["--prefix="++installPrefix] [] []
-        runBuilder (Make bindistFilesDir) ["install"] [] []
+        installTo NotRelocatable installPrefix
 
     phony "binary-dist-dir" $ do
         -- We 'need' all binaries and libraries
@@ -209,16 +229,6 @@ bindistRules = do
         cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache"]
 
 
-        -- The settings file must be regenerated by the bindist installation
-        -- logic to account for the environment discovered by the bindist
-        -- configure script on the host. Not on Windows, however, where
-        -- we do not ship a configure script with the bindist. See #20254.
-        --
-        -- N.B. we must do this after ghc-pkg has been run as it will go
-        -- looking for the settings files.
-        unless windowsHost $
-            removeFile (bindistFilesDir -/- "lib" -/- "settings")
-
         unless cross $ need ["docs"]
 
         -- TODO: we should only embed the docs that have been generated
@@ -252,42 +262,40 @@ bindistRules = do
         whenM (liftIO (IO.doesDirectoryExist (root -/- "manpage"))) $ do
           copyDirectory (root -/- "manpage") bindistFilesDir
 
-        -- These scripts are only necessary in the configure/install
-        -- workflow which is not supported on windows.
-        -- TODO: Instead of guarding against windows, we could offer the
-        -- option to make a relocatable, but not installable bindist on any
-        -- platform.
-        unless windowsHost $ do
-          -- We then 'need' all the files necessary to configure and install
-          -- (as in, './configure [...] && make install') this build on some
-          -- other machine.
-          need $ map (bindistFilesDir -/-)
-                    (["configure", "Makefile"] ++ bindistInstallFiles)
-          copyFile ("hadrian" -/- "bindist" -/- "config.mk.in") (bindistFilesDir -/- "config.mk.in")
-          generateBuildMk >>= writeFile' (bindistFilesDir -/- "build.mk")
-          copyFile ("hadrian" -/- "cfg" -/- "default.target.in") (bindistFilesDir -/- "default.target.in")
-          copyFile ("hadrian" -/- "cfg" -/- "default.host.target.in") (bindistFilesDir -/- "default.host.target.in")
-          forM_ bin_targets $ \(pkg, _) -> do
-            needed_wrappers <- pkgToWrappers pkg
-            forM_ needed_wrappers $ \wrapper_name -> do
-              let suffix = if useGhcPrefix pkg
-                             then "ghc-" ++ version
-                             else version
-              wrapper_content <- wrapper wrapper_name
-              let unversioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- wrapper_name
-                  versioned_wrapper = wrapper_name ++ "-" ++ suffix
-                  versioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- versioned_wrapper
-              -- Write the wrapper to the versioned path
-              writeFile' versioned_wrapper_path wrapper_content
-              -- Create a symlink from the non-versioned to the versioned.
-              liftIO $ do
-                IO.removeFile unversioned_wrapper_path <|> return ()
-                IO.createFileLink versioned_wrapper unversioned_wrapper_path
-
-
-    let buildBinDist :: Compressor -> Action ()
-        buildBinDist compressor = do
-            need ["binary-dist-dir"]
+        -- We then 'need' all the files necessary to configure and install
+        -- (as in, './configure [...] && make install') this build on some
+        -- other machine.
+        need $ map (bindistFilesDir -/-)
+                  (["configure", "Makefile"] ++ bindistInstallFiles)
+        copyFile ("hadrian" -/- "bindist" -/- "config.mk.in") (bindistFilesDir -/- "config.mk.in")
+        generateBuildMk >>= writeFile' (bindistFilesDir -/- "build.mk")
+        copyFile ("hadrian" -/- "cfg" -/- "default.target.in") (bindistFilesDir -/- "default.target.in")
+        copyFile ("hadrian" -/- "cfg" -/- "default.host.target.in") (bindistFilesDir -/- "default.host.target.in")
+
+        -- todo: do we need these wrappers on windows
+        forM_ bin_targets $ \(pkg, _) -> do
+          needed_wrappers <- pkgToWrappers pkg
+          forM_ needed_wrappers $ \wrapper_name -> do
+            let suffix = if useGhcPrefix pkg
+                           then "ghc-" ++ version
+                           else version
+            wrapper_content <- wrapper wrapper_name
+            let unversioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- wrapper_name
+                versioned_wrapper = wrapper_name ++ "-" ++ suffix
+                versioned_wrapper_path = bindistFilesDir -/- "wrappers" -/- versioned_wrapper
+            -- Write the wrapper to the versioned path
+            writeFile' versioned_wrapper_path wrapper_content
+            -- Create a symlink from the non-versioned to the versioned.
+            liftIO $ do
+              IO.removeFile unversioned_wrapper_path <|> return ()
+              IO.createFileLink versioned_wrapper unversioned_wrapper_path
+
+    let buildBinDist = buildBinDistX "binary-dist-dir" "bindist"
+        buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist"
+
+        buildBinDistX :: String -> FilePath -> Compressor -> Action ()
+        buildBinDistX target bindist_folder compressor = do
+            need [target]
 
             version        <- setting ProjectVersion
             targetPlatform <- setting TargetPlatformFull
@@ -296,15 +304,16 @@ bindistRules = do
 
             -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz
             tarPath <- builderPath (Tar Create)
-            cmd [Cwd $ root -/- "bindist"] tarPath
+            cmd [Cwd $ root -/- bindist_folder] tarPath
                 [ "-c", compressorTarFlag compressor, "-f"
                 , ghcVersionPretty <.> "tar" <.> compressorExtension compressor
                 , ghcVersionPretty ]
 
-    phony "binary-dist" $ buildBinDist Xz
-    phony "binary-dist-gzip" $ buildBinDist Gzip
-    phony "binary-dist-bzip2" $ buildBinDist Bzip2
-    phony "binary-dist-xz" $ buildBinDist Xz
+    forM_ [("binary", buildBinDist), ("reloc-binary", buildBinDistReloc)] $ \(name, mk_bindist) -> do
+      phony (name <> "-dist") $ mk_bindist Xz
+      phony (name <> "-dist-gzip") $ mk_bindist Gzip
+      phony (name <> "-dist-bzip2") $ mk_bindist Bzip2
+      phony (name <> "-dist-xz") $ mk_bindist Xz
 
     -- Prepare binary distribution configure script
     -- (generated under <ghc root>/distrib/configure by 'autoreconf')



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c37bb3f2b4faeaa6d14a135c40348b0fb4c62010...40074cf9bb35629d190956e2705c186640840831

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c37bb3f2b4faeaa6d14a135c40348b0fb4c62010...40074cf9bb35629d190956e2705c186640840831
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230817/284ebda3/attachment-0001.html>


More information about the ghc-commits mailing list