如何在我的dune项目中将包含路径标志传递给ocamlc/ocamlopt
我正在使用和编译使用。这个例子值得注意的是,它链接到两个C库:openssl和libev 初始尝试 这是我的shell.nix:如何在我的dune项目中将包含路径标志传递给ocamlc/ocamlopt,ocaml,nix,nixos,Ocaml,Nix,Nixos,我正在使用和编译使用。这个例子值得注意的是,它链接到两个C库:openssl和libev 初始尝试 这是我的shell.nix: with import <nixpkgs> { }; let spec = { buildInputs = with ocamlPackages; [ ocaml findlib dune # ocaml libs (and external library deps) cohttp-lwt-unix ope
with import <nixpkgs> { };
let spec = {
buildInputs = with ocamlPackages; [
ocaml
findlib
dune
# ocaml libs (and external library deps)
cohttp-lwt-unix openssl libev
]);
};
in runCommand "dummy" spec ""
with import <nixpkgs> { };
with ocamlPackages;
buildDunePackage {
pname = "dummy";
version = "0";
buildInputs = [
cohttp-lwt-unix
];
}
以及dune build server_example.exe的输出
...
/nix/store/3xwc1ip20b0p68sxqbjjll0va4pv5hbv-binutils-2.30/bin/ld: cannot find -lssl
/nix/store/3xwc1ip20b0p68sxqbjjll0va4pv5hbv-binutils-2.30/bin/ld: cannot find -lcrypto
/nix/store/3xwc1ip20b0p68sxqbjjll0va4pv5hbv-binutils-2.30/bin/ld: cannot find -lev
好吧,这并不奇怪,因为这些都在尼克松的非标准位置。我需要向dune调用的ocamlopt命令行添加相关路径,例如:-I${openssl.out}/lib-I${libev}/lib
现在,openssl包含pkg配置文件,但将pkg配置添加到我的shell.nix
中并没有明显的效果
第二次尝试,使用configurator
我曾经创建一个程序,将环境变量中的标志添加到dune可执行文件的构建标志中
shell.nix
with import <nixpkgs> { };
let spec = {
buildInputs = with ocamlPackages; [
ocaml
findlib
dune
configurator
# ocaml libs (and external library deps)
cohttp-lwt-unix openssl libev
]);
shellHook = ''
export OCAML_FLAGS="-I ${openssl.out}/lib -I ${libev}/lib"
'';
};
in runCommand "dummy" spec ""
形态/沙丘
(executable
(name discover)
(libraries dune.configurator))
config/discover.ml
open Sys
module C = Configurator.V1
let () =
C.main ~name:"getflags" (fun _c ->
let libs =
match getenv_opt "OCAML_FLAGS" with
| None -> []
| Some flags -> C.Flags.extract_blank_separated_words flags
in
C.Flags.write_sexp "flags.sexp" libs)
编译现在成功了,但这种编写自定义程序以获取环境变量并将其放入flags参数的方法似乎很笨拙
在dune中是否有实现这一点的标准方法(使用-I
向ocamlopt命令行添加路径)
如果没有,是否有更简单的方法从dune
文件中读取环境变量?使用stdenv.mkDerivation
或(如上所述)ocamlPackages.buildDunePackage
而不是runCommand
。后者导致的环境在NIX\u CFLAGS\u编译
或NIX\u LDFLAGS
环境变量中不包含openssl和libev。使用mkDerivation
会导致填充这些变量
一旦这些变量就位,通过dune
的编译就会成功,可执行文件将链接到libssl和libev
此外,没有必要显式包含libev和openssl,因为它们被声明为通过cohttplwtunix传播的构建输入
shell.nix:
with import <nixpkgs> { };
let spec = {
buildInputs = with ocamlPackages; [
ocaml
findlib
dune
# ocaml libs (and external library deps)
cohttp-lwt-unix openssl libev
]);
};
in runCommand "dummy" spec ""
with import <nixpkgs> { };
with ocamlPackages;
buildDunePackage {
pname = "dummy";
version = "0";
buildInputs = [
cohttp-lwt-unix
];
}
与导入{};
用奥卡姆包装;
构建数据包{
pname=“dummy”;
version=“0”;
构建输入=[
cohttplwtunix
];
}
有没有不这样做的原因?标记不是静态的:${openssl.dev}/lib
扩展到/nix/store/$somehash openssl-$version/lib
,其中$somehash
的更改频率可能比openssl版本更高。我可以直接传递它们,但它不雅观,并且需要随着时间的推移不断进行编辑。可能,让这更自动化的方法是将shell基于buildDunePackage
,而不是runCommand
。Nixpkgs手册的第1部分介绍了该功能。