Skip to content

Commit

Permalink
Switch to Bazel as the build system.
Browse files Browse the repository at this point in the history
  • Loading branch information
mboes committed Mar 5, 2018
1 parent 66a4a3b commit 4833ab7
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 52 deletions.
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,4 @@ cabal.sandbox.config
*.prof
*.aux
*.hp
.stack-work
.gradle
build
bazel-*
72 changes: 72 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package(default_visibility = ["//visibility:public"])

load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_test",
"haskell_binary",
"haskell_toolchain",
)

haskell_toolchain(
name = "ghc",
version = "8.2.2",
tools = "@ghc//:bin",
)

cc_library(
name = "bootstrap",
srcs = ["src/main/cc/bootstrap.c"],
deps = ["@ghc//:include", "@openjdk//:include"],
)

java_binary(
name = "base-jar",
srcs = glob(["src/main/java/**"]),
main_class = "io.tweag.jarify.JarifyMain",
)

haskell_binary(
name = "jarify",
src_strip_prefix = "src/main/haskell",
srcs = ["src/main/haskell/Main.hs"],
data = [
":base-jar",
"@org_nixos_patchelf//:patchelf",
"@gcc//:bin",
],
args = ["--base-jar", "$(location :base-jar)"],
prebuilt_dependencies = [
"base",
"bytestring",
"directory",
"filepath",
"process",
"regex-tdfa",
"temporary",
"text",
"unix",
"zip-archive",
],
)

haskell_binary(
name = "hello",
src_strip_prefix = "src/test/haskell/hello",
srcs = ["src/test/haskell/hello/Main.hs"],
compiler_flags = ["-dynamic", "-pie"],
prebuilt_dependencies = ["base"],
testonly = True,
)

sh_test(
name = "hello-test",
srcs = ["test-cmd.sh"],
args = [
"$(location :jarify)",
"--base-jar",
"$(location :base-jar)",
"$(location :hello)",
],
data = [":jarify", ":base-jar", ":hello"],
timeout = "short",
)
98 changes: 98 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
workspace(name = "io_tweag_jarify")

http_archive(
name = "io_tweag_rules_haskell",
strip_prefix = "rules_haskell-078fa0b7c557262571a2b25da34a0a0b375299e3",
urls = ["https://github.com/tweag/rules_haskell/archive/078fa0b7c557262571a2b25da34a0a0b375299e3.tar.gz"],
)

load("@io_tweag_rules_haskell//haskell:repositories.bzl", "haskell_repositories")
haskell_repositories()

http_archive(
name = "io_tweag_rules_nixpkgs",
strip_prefix = "rules_nixpkgs-0.1.1",
urls = ["https://github.com/tweag/rules_nixpkgs/archive/v0.1.1.tar.gz"],
)

new_http_archive(
name = "org_nixos_patchelf",
strip_prefix = "patchelf-1fa4d36fead44333528cbee4b5c04c207ce77ca4",
urls = ["https://github.com/NixOS/patchelf/archive/1fa4d36fead44333528cbee4b5c04c207ce77ca4.tar.gz"],
build_file_content = """
cc_binary(
name = "patchelf",
srcs = ["src/patchelf.cc", "src/elf.h"],
copts = ["-DPAGESIZE=4096", '-DPACKAGE_STRING=\\\\"patchelf\\\\"'],
visibility = [ "//visibility:public" ],
)
"""
)

load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl",
"nixpkgs_git_repository",
"nixpkgs_package",
)

nixpkgs_git_repository(
name = "nixpkgs",
# Nixpkgs from 2018-02-23
revision = "1c3b6d509d06af14b1858ffa2d27f3c902f549bd",
)

prebuilt_packages = [
"base",
"bytestring",
"directory",
"filepath",
"process",
"regex-tdfa",
"temporary",
"text",
"unix",
"zip-archive",
]

nixpkgs_package(
name = "ghc",
repository = "@nixpkgs",
nix_file_content = """
let pkgs = import <nixpkgs> {{}};
in pkgs.haskell.packages.ghc822.ghcWithPackages (p: with p; [{0}])
""".format(" ".join(prebuilt_packages)),
build_file_content = """
package(default_visibility = [ "//visibility:public" ])
filegroup(
name = "bin",
srcs = glob(["nix/bin/*"]),
)
cc_library(
name = "include",
hdrs = glob(["nix/lib/ghc-*/include/**/*.h"]),
strip_include_prefix = glob(["nix/lib/ghc-*/include"], exclude_directories=0)[0],
)
"""
)

nixpkgs_package(
name = "gcc",
repository = "@nixpkgs",
)

register_toolchains("//:ghc")

nixpkgs_package(
name = "openjdk",
repository = "@nixpkgs",
build_file_content = """
package(default_visibility = ["//visibility:public"])
cc_library(
name = "include",
hdrs = glob(["nix/include/*.h"]),
strip_include_prefix = "nix/include",
)
"""
)
43 changes: 24 additions & 19 deletions src/main/haskell/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ import Data.Text (pack, strip, unpack)
import Data.List (intercalate, isInfixOf)
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString as SBS
import System.Directory (copyFile, doesFileExist)
import System.Directory
( canonicalizePath
, copyFile
, getCurrentDirectory
)
import System.Environment (getArgs, getExecutablePath)
import System.FilePath ((</>), (<.>), isAbsolute, takeBaseName, takeFileName)
import System.FilePath ((</>), (<.>), isAbsolute, takeFileName)
import System.Exit (ExitCode(..))
import System.Info (os)
import System.IO (hPutStrLn, stderr)
import System.IO.Temp (withSystemTempFile, withSystemTempDirectory)
import System.Posix.Files (createSymbolicLink)
import System.Posix.Files (createSymbolicLink, ownerModes, setFileMode)
import System.Process
( CreateProcess(..)
, callProcess
Expand All @@ -42,16 +46,14 @@ patchElf :: FilePath -> IO ()
patchElf exe = do
rpath <- readProcess "patchelf" ["--print-rpath", exe] ""
let newrpath = intercalate ":" ["$ORIGIN", stripString rpath]
callProcess "patchelf" ["--set-rpath", newrpath, exe]
callProcess "../org_nixos_patchelf/patchelf" ["--set-rpath", newrpath, exe]

doPackage :: FilePath -> FilePath -> IO ()
doPackage baseJar cmd = do
doPackage baseJar cmdpath = do
jarbytes <- LBS.readFile baseJar
cmdpath <- doesFileExist cmd >>= \case
False -> stripString <$> readProcess "which" [cmd] ""
True -> return cmd
(hsapp, libs) <- withSystemTempFile "hsapp" $ \tmp _ -> do
copyFile cmdpath tmp
setFileMode tmp ownerModes
patchElf tmp
ldd <- case os of
"darwin" -> do
Expand Down Expand Up @@ -95,24 +97,27 @@ doPackage baseJar cmd = do
fromArchive $
foldr addEntryToArchive emptyArchive (cmdentry : libentries)
newjarbytes = fromArchive $ addEntryToArchive appzip (toArchive jarbytes)
LBS.writeFile ("." </> takeBaseName cmd <.> "jar") newjarbytes
LBS.writeFile ("/tmp/" </> cmdpath <.> "jar") newjarbytes
where
mkEntry file = toEntry (takeFileName file) 0 <$> LBS.readFile file

-- We make a library which depends on all the libraries that go into the jar.
-- This removes the need to fiddle with the rpaths of the various libraries
-- and the application executable.
makeHsTopLibrary :: FilePath -> [FilePath] -> IO LBS.ByteString
makeHsTopLibrary hsapp libs = withSystemTempDirectory "libhsapp" $ \d -> do
let f = d </> "libhsapp.so"
createSymbolicLink hsapp (d </> "hsapp")
-- Changing the directory is necessary for gcc to link hsapp with a
-- relative path. "-L d -l:hsapp" doesn't work in centos 6 where the
-- path to hsapp in the output library ends up being absolute.
callProcessCwd d "gcc" $
[ "-shared", "-Wl,-z,origin", "-Wl,-rpath=$ORIGIN", "hsapp"
, "-o", f] ++ libs
LBS.fromStrict <$> SBS.readFile f
makeHsTopLibrary hsapp libs = do
workspace <- getCurrentDirectory
withSystemTempDirectory "libhsapp" $ \d -> do
let f = d </> "libhsapp.so"
abspath <- canonicalizePath hsapp
createSymbolicLink abspath (d </> "hsapp")
-- Changing the directory is necessary for gcc to link hsapp with
-- a relative path. "-L d -l:hsapp" doesn't work in centos 6 where the
-- path to hsapp in the output library ends up being absolute.
callProcessCwd d (workspace </> "../gcc/nix/bin/gcc") $
[ "-shared", "-Wl,-z,origin", "-Wl,-rpath=$ORIGIN", "hsapp"
, "-o", f] ++ libs
LBS.fromStrict <$> SBS.readFile f

-- This is a variant of 'callProcess' which takes a working directory.
callProcessCwd :: FilePath -> FilePath -> [String] -> IO ()
Expand Down
30 changes: 0 additions & 30 deletions src/test/haskell/hello/LICENSE

This file was deleted.

File renamed without changes.

0 comments on commit 4833ab7

Please sign in to comment.