-- Copyright (C) 2016-2017 Red Hat, Inc. -- -- This library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with this library; if not, see . {-# LANGUAGE CPP #-} module Main(main) where import Data.List(isPrefixOf) import Distribution.PackageDescription(Executable(..), GenericPackageDescription(..), HookedBuildInfo, PackageDescription(..)) import Distribution.Simple(defaultMainWithHooks, simpleUserHooks) import Distribution.Simple.InstallDirs(InstallDirs(..), fromPathTemplate, toPathTemplate) import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..)) import Distribution.Simple.UserHooks(UserHooks(..)) import System.FilePath(()) #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2, 0, 0) import Distribution.Types.UnqualComponentName(unUnqualComponentName) import Distribution.Types.ExecutableScope(ExecutableScope(..)) import Distribution.Simple.Setup(ConfigFlags) #else import Distribution.Simple.Install(install) import Distribution.Simple.Setup(ConfigFlags, CopyFlags) #endif main :: IO () main = defaultMainWithHooks bdcsHooks -- Handle the libexec paths, and differences between Cabal-1.x and Cabal-2.x. -- -- On Cabal-2.x, we can specify a scope of "private" on libexec executables. -- This can be done directly in the .cabal file when we remove support for Cabal < 2.0. #if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2, 0, 0) bdcsHooks :: UserHooks bdcsHooks = simpleUserHooks { confHook = bdcsConf } bdcsConf :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo bdcsConf (descr, hbi) flags = do lbi <- confHook simpleUserHooks (descr, hbi) flags -- Modify the executable list to change the scope of the libexec executables let localDesc = localPkgDescr lbi scopedLbi = lbi { localPkgDescr = localDesc { executables = map mangleExec (executables localDesc) } } -- Add weldr/ to the libexecdir return $ addLibexecWeldr scopedLbi where mangleExec :: Executable -> Executable mangleExec exe = if isSubcommand (unUnqualComponentName $ exeName exe) then exe{exeScope = ExecutablePrivate} else exe #else -- On Cabal-1.x, change the destination directory of subcomponents during the copy step bdcsHooks :: UserHooks bdcsHooks = simpleUserHooks { confHook = bdcsConf, copyHook = bdcsCopy } bdcsConf :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo bdcsConf (descr, hbi) flags = addLibexecWeldr <$> confHook simpleUserHooks (descr, hbi) flags bdcsCopy :: PackageDescription -> LocalBuildInfo -> UserHooks -> CopyFlags -> IO () bdcsCopy pkg lbi _ flags = do -- First, install everything that's not a subcommand. That is almost everything -- listed in the cabal file. let (mainPkg, mainLbi) = extractMainComponents pkg lbi install mainPkg mainLbi flags -- Second, install only the subcommands into $prefix/libexec/weldr. let (subPkg, subLbi) = extractSubComponents pkg lbi install subPkg subLbi flags extractMainComponents :: PackageDescription -> LocalBuildInfo -> (PackageDescription, LocalBuildInfo) extractMainComponents pkg lbi = let pkg' = pkg { executables = filter (not . isSubcommand . exeName) (executables pkg) } in (pkg', lbi) extractSubComponents :: PackageDescription -> LocalBuildInfo -> (PackageDescription, LocalBuildInfo) extractSubComponents pkg lbi = let dest = libexecdir (installDirTemplates lbi) pkg' = pkg { executables = filter (isSubcommand . exeName) (executables pkg) } lbi' = lbi { installDirTemplates = (installDirTemplates lbi) { bindir = dest } } in (pkg', lbi') #endif isSubcommand :: String -> Bool isSubcommand s = "inspect-" `isPrefixOf` s || "bdcs-" `isPrefixOf` s -- Make sure $libexecdir gets "weldr/" appended to it. This will affect both the installation location -- for anything that should go into $libexecdir (like our subcommand programs) as well as the auto -- generated Paths_bdcs.hs file. -- -- This also means if you pass --libexecdir= to "cabal configure" or any other program, you should not -- add "weldr/" to it. Otherwise you'll get it in there twice. addLibexecWeldr :: LocalBuildInfo -> LocalBuildInfo addLibexecWeldr lbi = let dest = mangle $ libexecdir $ installDirTemplates lbi in lbi { installDirTemplates = (installDirTemplates lbi) { libexecdir = dest } } where mangle = toPathTemplate . ( "weldr") . fromPathTemplate