Stack Build 找不到本地库
Stack Build Cannot Find Local Library
我使用 GHC 成功地复制了这个例子。
https://wiki.haskell.org/Calling_Haskell_from_C
最终目标是在 Haskell 中编写我的程序的 99%,然后从用 C:
编写的事件循环中调用它
#include <HsFFI.h>
#ifdef __GLASGOW_HASKELL__
#include "../.stack-work/dist/x86_64-linux/Cabal-2.4.0.1/build/Lib_stub.h"
extern void __stginit_Lib(void);
#endif
#include <stdio.h>
#include <time.h>
extern void hs_add_root (void (*init_root)(void));
int main(int argc, char *argv[])
{
int i;
hs_init(&argc, &argv);
#ifdef __GLASGOW_HASKELL__
hs_add_root(__stginit_Lib);
#endif
for (int m = 0; m < 10; ++m) {
i = fibonacci_hs(42);
printf("Fibonacci: %d\n", i);
}
hs_exit();
return 0;
}
C 中 运行 事件循环的动机是,根据我的阅读,强制求值 X times/second 在 Haskell 中是困难的或不可能的。
这里是package.yaml:
name: c-loop
version: 0.1.0.0
github: "githubuser/c-loop"
license: BSD3
author: "Author name here"
maintainer: "example@example.com"
copyright: "2019 Author name here"
extra-source-files:
- README.md
- ChangeLog.md
# Metadata used when publishing your package
# synopsis: Short description of your package
# category: Web
# To avoid duplicated efforts in documentation and dealing with the
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description: Please see the README on GitHub at <https://github.com/githubuser/c-loop#readme>
dependencies:
- base >= 4.7 && < 5
library:
source-dirs: src
executables:
c-loop-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
- -fobject-code
# - -no-hs-main
- --make -no-hs-main -optc-O ./c/eventLoop.c Lib -o eventLoop
dependencies:
- c-loop
tests:
c-loop-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- c-loop
当我运行:
$ stack build
我明白了:
<no location info>: error: module ‘Lib’ cannot be found locally
有人知道这是怎么回事吗?
顺便说一句,您的动机似乎被误导了。我认为拥有一个 C 事件循环没有任何好处,它的唯一目的是定期 "force evaluation"。您可以在 Haskell 中做到这一点。
您上面的示例中出现问题的可能是 ghc-options
中的 Lib
。但是,您应该使用其他 Cabal 字段来代替,这将使事情工作得更顺利。
以下是如何让您的最小示例使用 Stack。使用下面列出的四个文件和 运行 stack build
,然后 stack exec c-loop-exe
.
创建一个新目录
几点:
- 您可以使用
package.yaml
文件执行此操作,但您必须转换 Cabal 语法。
- 您不再需要那些
__stginit
和 hs_add_root
垃圾,除非您使用的是 < 7.2 的 GHC。
- 如果正确设置了 Cabal 文件(即使用
c-sources
),则不需要 hard-code 存根的路径。
-opt-O2
标志是不必要的。这是 Stack 的默认值。
四个文件的内容:
-- stack.yaml
resolver: lts-13.21
packages:
- .
-- c-loop.cabal
cabal-version: 1.12
name: c-loop
version: 0.1.0.0
build-type: Simple
executable c-loop-exe
main-is: src/Lib.hs
ghc-options: -no-hs-main
c-sources: c/eventLoop.c
build-depends:
base >=4.7 && <5
default-language: Haskell2010
-- c/eventLoop.c
#include <stdio.h>
#include <time.h>
#include "HsFFI.h"
#include "Lib_stub.h"
int main(int argc, char *argv[])
{
int i;
hs_init(&argc, &argv);
for (int m = 0; m < 10; ++m) {
i = fibonacci_hs(42);
printf("Fibonacci: %d\n", i);
}
hs_exit();
return 0;
}
-- src/Lib.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Lib where
import Foreign.C.Types
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt
我使用 GHC 成功地复制了这个例子。
https://wiki.haskell.org/Calling_Haskell_from_C
最终目标是在 Haskell 中编写我的程序的 99%,然后从用 C:
编写的事件循环中调用它#include <HsFFI.h>
#ifdef __GLASGOW_HASKELL__
#include "../.stack-work/dist/x86_64-linux/Cabal-2.4.0.1/build/Lib_stub.h"
extern void __stginit_Lib(void);
#endif
#include <stdio.h>
#include <time.h>
extern void hs_add_root (void (*init_root)(void));
int main(int argc, char *argv[])
{
int i;
hs_init(&argc, &argv);
#ifdef __GLASGOW_HASKELL__
hs_add_root(__stginit_Lib);
#endif
for (int m = 0; m < 10; ++m) {
i = fibonacci_hs(42);
printf("Fibonacci: %d\n", i);
}
hs_exit();
return 0;
}
C 中 运行 事件循环的动机是,根据我的阅读,强制求值 X times/second 在 Haskell 中是困难的或不可能的。
这里是package.yaml:
name: c-loop
version: 0.1.0.0
github: "githubuser/c-loop"
license: BSD3
author: "Author name here"
maintainer: "example@example.com"
copyright: "2019 Author name here"
extra-source-files:
- README.md
- ChangeLog.md
# Metadata used when publishing your package
# synopsis: Short description of your package
# category: Web
# To avoid duplicated efforts in documentation and dealing with the
# complications of embedding Haddock markup inside cabal files, it is
# common to point users to the README.md file.
description: Please see the README on GitHub at <https://github.com/githubuser/c-loop#readme>
dependencies:
- base >= 4.7 && < 5
library:
source-dirs: src
executables:
c-loop-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
- -fobject-code
# - -no-hs-main
- --make -no-hs-main -optc-O ./c/eventLoop.c Lib -o eventLoop
dependencies:
- c-loop
tests:
c-loop-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- c-loop
当我运行:
$ stack build
我明白了:
<no location info>: error: module ‘Lib’ cannot be found locally
有人知道这是怎么回事吗?
顺便说一句,您的动机似乎被误导了。我认为拥有一个 C 事件循环没有任何好处,它的唯一目的是定期 "force evaluation"。您可以在 Haskell 中做到这一点。
您上面的示例中出现问题的可能是 ghc-options
中的 Lib
。但是,您应该使用其他 Cabal 字段来代替,这将使事情工作得更顺利。
以下是如何让您的最小示例使用 Stack。使用下面列出的四个文件和 运行 stack build
,然后 stack exec c-loop-exe
.
几点:
- 您可以使用
package.yaml
文件执行此操作,但您必须转换 Cabal 语法。 - 您不再需要那些
__stginit
和hs_add_root
垃圾,除非您使用的是 < 7.2 的 GHC。 - 如果正确设置了 Cabal 文件(即使用
c-sources
),则不需要 hard-code 存根的路径。 -opt-O2
标志是不必要的。这是 Stack 的默认值。
四个文件的内容:
-- stack.yaml
resolver: lts-13.21
packages:
- .
-- c-loop.cabal
cabal-version: 1.12
name: c-loop
version: 0.1.0.0
build-type: Simple
executable c-loop-exe
main-is: src/Lib.hs
ghc-options: -no-hs-main
c-sources: c/eventLoop.c
build-depends:
base >=4.7 && <5
default-language: Haskell2010
-- c/eventLoop.c
#include <stdio.h>
#include <time.h>
#include "HsFFI.h"
#include "Lib_stub.h"
int main(int argc, char *argv[])
{
int i;
hs_init(&argc, &argv);
for (int m = 0; m < 10; ++m) {
i = fibonacci_hs(42);
printf("Fibonacci: %d\n", i);
}
hs_exit();
return 0;
}
-- src/Lib.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Lib where
import Foreign.C.Types
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt