Сборка стека не может найти локальную библиотеку - PullRequest
0 голосов
/ 11 мая 2019

Я успешно реплицировал этот пример, используя сам GHC.

https://wiki.haskell.org/Calling_Haskell_from_C

Конечная цель - написать 99% моей программы на Haskell, а затем вызвать ее из цикла событий, написанного на 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 раз в секунду сложно или невозможно в 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

Кто-нибудь знаетчто происходит?

1 Ответ

3 голосов
/ 12 мая 2019

Кстати, ваша мотивация кажется ошибочной.Я не думаю, что есть какая-то польза от цикла событий C, единственной целью которого является «форсировать оценку» по регулярному графику.Вы можете сделать это в Хаскеле просто отлично.

В вашем примере, что идет не так, вероятно, Lib в ghc-options.Однако есть другие поля Cabal, которые вы должны использовать вместо этого, что сделает работу более плавной.

Вот как получить минимальный пример работы со стеком.Создайте новый каталог с четырьмя файлами, перечисленными ниже, и запустите stack build, затем stack exec c-loop-exe.

Несколько пунктов:

  • Вы можете сделать это с помощью package.yaml файла, но вам придется преобразовать синтаксис Cabal в *. 1015 *
  • Вам больше не нужен весь этот мусор __stginit и hs_add_root, если только вы не используете GHC <7.2. </li>
  • Вам не нужно жестко кодировать путь для заглушки, если вы правильно настроили файл Cabal (т. Е., Используя c-sources).
  • Флаг -opt-O2 не нужен.Это стек по умолчанию.

Содержимое четырех файлов:

-- 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
...