【问题标题】:Use relative paths for extra-lib-dirs on cabal对 cabal 上的额外库目录使用相对路径
【发布时间】:2014-08-18 03:24:10
【问题描述】:

我有一个包含 Makefile 的 C 库“myboo”。我想为这个库做一个包装。 我不想将它安装到 /usr/local 中,因为“myboo”不是主要模块。 此外,建议我不要将“myboo”构建为动态库 但作为一个静态库。

我制作自定义 Setup.py 来构建“myboo”;

main :: IO ()
main = defaultMainWithHooks simpleUserHooks {
           preBuild = \a b -> makeLib a b >> preBuild simpleUserHooks a b
           }

makeLib :: Args -> BuildFlags -> IO ()
makeLib _ flags = do
  let verbosity = fromFlag $ buildVerbosity flags
  cflags <- lookupEnv "CFLAGS" >>= return . maybe "" id
  setEnv "CFLAGS" $ "-fPIC" ++ (' ' : cflags)
  rawSystemExit verbosity "env" ["make", "--directory=myboo", "libmyboo.a"]

我安排 myboo.cabal 将我的 haskell 代码链接到 C 库;

library
  exposed-modules:     MyBoo
  build-depends:       base >=4.7 && <4.8
  hs-source-dirs:      src
  default-language:    Haskell2010
  include-dirs: myboo
  extra-libraries: myboo
  extra-lib-dirs: myboo

当我运行“cabal build”时,我收到了以下消息。

myboo-0.1.0.0: library-dirs: myboo is a relative path which makes no sense (as
there is nothing for it to be relative to). You can make paths relative to the
package database itself by using ${pkgroot}. (use --force to override)

如果我写“extra-lib-dirs:/absolute/path/to/working/dir/myboo”,它似乎运行良好。 但这不是好方法,因为 /absolute/... 只是一个工作目录。

我应该如何修复上述错误消息?我的环境在这里;

% ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.2
% cabal --version
cabal-install version 1.20.0.2
using version 1.20.0.0 of the Cabal library
% cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04 LTS"

【问题讨论】:

    标签: haskell cabal


    【解决方案1】:

    您可以编写自己的 Setup.hs 并设置 Distribution.Simple.confHook。在您的钩子函数中,修改Distribution.PackageDescription.extraLibDirs 以包含该目录。

    请注意,您还需要将 cabal 文件中的 build-type 更改为 Custom。

    这是Setup.hs 的链接,我在其中完成了我所写的操作。

    【讨论】:

      【解决方案2】:

      有点晚了,但是……

      现在您可以使用相对路径在stack.yaml 中设置extra-include-dirs 和extra-lib-dirs 选项。例如,对于某些包A,它看起来像这样:

      extra-include-dirs:
      - ../my-c-lib/src
      
      extra-lib-dirs:
      - ../my-c-lib/build
      

      假设A 和my-c-lib 都存储在同一个文件夹中。

      就是这样。它不需要您设置LD_LIBRARY_PATH 变量(直到您运行可执行文件)。但是,如果你有一个使用A 的包B,则必须将A 的extra-..-dirs 添加到B 的stack.yaml。否则你会得到Missing C library 错误。另外,这里必须设置LD_LIBRARY_PATH,以防止B构建过程中出现can't load .so/.DLL错误。

      基本上,这是构建本地软件包的一种解决方法。我不会将它用于公共包,因为它会强制用户修改 stack.yaml 或将依赖包存储在同一文件夹中。

      【讨论】:

      • 你是如何让它与相对路径一起工作的?手册说路径应该是绝对的docs.haskellstack.org/en/stable/yaml_configuration/…
      • @Flip 好吧,除此之外我什么都没做。通常,当我必须处理 ffi 时,我只做两个项目。它们都位于一个名为 root-dir 的目录中。因此,例如,让 haskell 部分为root-dir/some-hs,C 部分为root-dir/some-c。正如我在答案中显示的那样,我设置了extra-include-dirs 和extra-lib-dirs。而且它可以正常工作(假设C部分中有src和build文件夹)。我很高兴它有效,否则处理起来会很痛苦。我最近什至做了一个这样的项目,它仍然有效。让我知道它是否不适合你。我会尽力帮忙的。
      • @Flip 另外,我认为您不必像我的那样有层次结构。我相信你可以使用../../ 或../../../ 但我没有尝试过。所以我不能确定。无论如何,如果允许../ 而不允许../../,那就太奇怪了。我希望这样的技巧不会在堆栈的任何版本中“修复”:D
      猜你喜欢
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 2013-02-20
      • 2011-12-11
      • 2016-09-14
      相关资源
      最近更新 更多