From 5730137d689aba41d66947b63e87b0666dba269a Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Tue, 30 Apr 2019 11:56:35 +0200 Subject: [PATCH 1/4] Hazel: Don't run ./configure in repository rule This violates hermeticity, as the ./configure script might pick up a system compiler, and system libraries, which are later replaced through library dependencies or cc toolchains. --- hazel/hazel_base_repository/cabal2bazel.hs | 47 ++-------------------- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/hazel/hazel_base_repository/cabal2bazel.hs b/hazel/hazel_base_repository/cabal2bazel.hs index 282bb71a9..7723f0e44 100644 --- a/hazel/hazel_base_repository/cabal2bazel.hs +++ b/hazel/hazel_base_repository/cabal2bazel.hs @@ -13,23 +13,18 @@ module Main (main) where #if MIN_VERSION_Cabal(2,2,0) import Distribution.PackageDescription.Parsec - (readGenericPackageDescription, parseHookedBuildInfo, runParseResult) -import qualified Data.ByteString.Char8 as BS.C8 + (readGenericPackageDescription) #else import Distribution.PackageDescription.Parse - (readGenericPackageDescription, parseHookedBuildInfo, ParseResult(..)) + (readGenericPackageDescription) #endif -import Distribution.Text (display, simpleParse) +import Distribution.Text (simpleParse) import Distribution.Verbosity (normal) import System.Environment (getArgs) -import System.FilePath ((<.>)) -import System.Process (callProcess) import qualified Data.Map.Strict as Map -import qualified Distribution.Package as P import qualified Distribution.PackageDescription as P -import qualified System.Directory as Directory import Description import Flatten @@ -43,7 +38,7 @@ main = do Nothing -> error $ "Error parsing ghc version: " ++ show ghcVersionStr Just v -> v packageFlags = parseFlags flagArgs - desc <- maybeConfigure $ flattenToDefaultFlags ghcVersion packageFlags gdesc + desc = flattenToDefaultFlags ghcVersion packageFlags gdesc writeFile outFile $ show $ renderStatements [Assign "package" $ packageDescriptionExpr desc] @@ -52,37 +47,3 @@ parseFlags = \case "-flag-on":flag:etc -> Map.insert (P.mkFlagName flag) True (parseFlags etc) "-flag-off":flag:etc -> Map.insert (P.mkFlagName flag) False (parseFlags etc) _ -> Map.empty - -maybeConfigure :: P.PackageDescription -> IO P.PackageDescription -maybeConfigure desc = whenConfiguring $ do - callProcess "./configure" [] - let buildInfoFile = display (P.packageName desc) <.> "buildinfo" - buildInfoExists <- Directory.doesFileExist buildInfoFile - if buildInfoExists - then processBuildInfoFile buildInfoFile - else return desc - where -#if MIN_VERSION_Cabal(2,2,0) - whenConfiguring m = case P.buildType desc of - P.Configure -> m - _ -> return desc - - processBuildInfoFile buildInfoFile = do - cs <- BS.C8.readFile buildInfoFile - case runParseResult (parseHookedBuildInfo cs) of - (_warnings, Left (_maybeVersion, es)) -> - error $ "Error reading buildinfo " ++ show buildInfoFile ++ ": " ++ show es - (_warnings, Right hookedBI) -> - return $ P.updatePackageDescription hookedBI desc -#else - whenConfiguring m = case P.buildType desc of - Just P.Configure -> m - _ -> return desc - - processBuildInfoFile buildInfoFile = do - cs <- readFile buildInfoFile - case parseHookedBuildInfo cs of - ParseFailed e -> error $ "Error reading buildinfo " ++ show buildInfoFile - ++ ": " ++ show e - ParseOk _ hookedBI -> return $ P.updatePackageDescription hookedBI desc -#endif From cea4e472796d61ac8702797e84a7abd38315ff05 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Tue, 30 Apr 2019 14:58:27 +0200 Subject: [PATCH 2/4] Hazel: Run ./configure in build rule --- .../cabal2bazel/bzl/cabal_package.bzl | 59 +++++++++++++++---- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/hazel/third_party/cabal2bazel/bzl/cabal_package.bzl b/hazel/third_party/cabal2bazel/bzl/cabal_package.bzl index 16d5c3b16..4d9a23f5b 100644 --- a/hazel/third_party/cabal2bazel/bzl/cabal_package.bzl +++ b/hazel/third_party/cabal2bazel/bzl/cabal_package.bzl @@ -71,6 +71,44 @@ def _get_core_dependency_includes(ghc_workspace): "unix": "{}//:unix-includes".format(ghc_workspace), } +# Some packages, such as network, include the config.log and config.status +# files, generated by the ./configure script, in their extraTmpFiles. These +# files contain information specific to the build host, which defeates +# distributed caching. Here we black-list any such files and exclude them +# from the headers attribute to cc_library. +_header_blacklist = [ + "autom4te.cache", + "config.log", + "config.status", +] + +def _configure(desc): + outputs = [ + f + for f in desc.extraTmpFiles + if f.split("/")[-1] not in _header_blacklist + ] + native.genrule( + name = "run-configure", + cmd = "\n".join([ + # Run configure in it's containing directory, so that generated + # files are in the right location. Fixup a relative path to CC to + # take the new working directory into account (relative paths + # remain relative). + '( UP="$$(sed \'s/[^\\/]\\+/../g\' <<<"$$(dirname "$(location configure)")")" && \\', + ' fixpath() { case "$$1" in /*) echo "$$1" ;; *) echo "$$UP/$$1" ;; esac; } && \\', + ' cd "$$(dirname "$(location configure)")" && \\', + ' PATH="$$(fixpath "$$(dirname "$(CC)")"):$$PATH" CC="$$(fixpath "$(CC)")" CFLAGS="$(CC_FLAGS)" ./configure )', + ] + [ + "mkdir -p $$(dirname $(location {out})) && cp $(rootpath {out}) $(location {out})".format(out = out) + for out in outputs + ]), + tools = ["configure"], + toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"], + srcs = native.glob(["**"], exclude = outputs), + outs = outputs, + ) + def _paths_module(desc): return "Paths_" + desc.package.pkgName.replace("-", "_") @@ -389,23 +427,17 @@ def _get_build_attrs( ) globbed_headers = native.glob([ paths.normalize(f) - for f in desc.extraSrcFiles + desc.extraTmpFiles - ]) - - # Some packages, such as network, include the config.log and config.status - # files, generated by the ./configure script, in their extraTmpFiles. These - # files contain information specific to the build host, which defeates - # distributed caching. Here we black-list any such files and exclude them - # from the headers attribute to cc_library. - header_blacklist = [ - "config.log", - "config.status", + for f in desc.extraSrcFiles + ]) + [ + paths.normalize(f) + for f in desc.extraTmpFiles ] + headers = depset( [ hdr for hdr in globbed_headers - if hdr.split("/")[-1] not in header_blacklist + if hdr.split("/")[-1] not in _header_blacklist ] + install_includes, ) @@ -483,6 +515,9 @@ def cabal_haskell_package( """ name = description.package.pkgName + if description.buildTypeRaw == "Configure": + _configure(description) + cabal_paths( name = _paths_module(description), package = name.replace("-", "_"), From aede580c388dacb4b1986df2b63cf1485d8c55ee Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Tue, 30 Apr 2019 16:34:45 +0200 Subject: [PATCH 3/4] Patch network.cabal Running the ./configure script during build improves upon the hermeticity issues. However, it prevents the use of Cabal buildinfo files. The network configure script generates such a file that is then meant to be used to patch the Cabal package definition. However, we can work around this by instead defining conditional flags in the network cabal file. --- hazel/third_party/haskell/network.patch | 22 ++++++++++++++++++++++ hazel/workspace.bzl | 1 + 2 files changed, 23 insertions(+) create mode 100644 hazel/third_party/haskell/network.patch diff --git a/hazel/third_party/haskell/network.patch b/hazel/third_party/haskell/network.patch new file mode 100644 index 000000000..fe9551db3 --- /dev/null +++ b/hazel/third_party/haskell/network.patch @@ -0,0 +1,22 @@ +--- network.cabal.orig 2019-04-30 16:22:51.017832083 +0200 ++++ network.cabal 2019-04-30 16:33:48.037415801 +0200 +@@ -71,8 +71,19 @@ + includes: HsNet.h HsNetDef.h + install-includes: HsNet.h HsNetDef.h + c-sources: cbits/HsNet.c ++ ++ if os(windows) ++ c-sources: cbits/initWinSock.c cbits/winSockErr.c cbits/asyncAccept.c ++ else ++ c-sources: cbits/ancilData.c ++ + ghc-options: -Wall -fwarn-tabs + ++ if !os(windows) ++ ghc-options: -D_GNU_SOURCE ++ ghc-prof-options: -D_GNU_SOURCE ++ cc-options: -D_GNU_SOURCE ++ + test-suite spec + hs-source-dirs: tests + main-is: Spec.hs diff --git a/hazel/workspace.bzl b/hazel/workspace.bzl index 936b3525a..707fb377a 100644 --- a/hazel/workspace.bzl +++ b/hazel/workspace.bzl @@ -101,6 +101,7 @@ cc_library( pkgs = packages, extra_pkgs = { "unix-time": {"version": "0.4.5", "sha256": "fe7805c62ad682589567afeee265e6e230170c3941cdce479a2318d1c5088faf"}, + "network": {"version": "2.8.0.0", "sha256": "c8905268b7e3b4cf624a40245bf11b35274a6dd836a5d4d531b5760075645303", "patches": ["@ai_formation_hazel//third_party/haskell:network.patch"]}, }, ), core_packages = core_packages, From caf2a237dea6e6958c185bef8e1975210a05a479 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 3 May 2019 16:44:15 +0200 Subject: [PATCH 4/4] Add network to Windows CI --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e41bf2923..581bb26ff 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -29,6 +29,7 @@ jobs: /c/bazel/bazel.exe build --config windows "@haskell_conduit//..." /c/bazel/bazel.exe build --config windows "@haskell_fuzzyset//..." /c/bazel/bazel.exe build --config windows "@haskell_lens//..." + /c/bazel/bazel.exe build --config windows "@haskell_network//..." /c/bazel/bazel.exe build --config windows "@haskell_text__metrics//..." /c/bazel/bazel.exe build --config windows "@haskell_cryptonite//..." /c/bazel/bazel.exe build --config windows "@haskell_unix__compat//..." @@ -54,7 +55,6 @@ jobs: # /c/bazel/bazel.exe build --config windows "@haskell_pretty__show//..." # FIXME: need custom builds - # /c/bazel/bazel.exe build --config windows "@haskell_network_1843485230//..." # /c/bazel/bazel.exe build --config windows "@haskell_postgresql_libpq_275795853//..." # FIXME: depends on network