С haskell инструментом для встряхивания. Используйте местную библиотеку stati c c - PullRequest
0 голосов
/ 16 марта 2020

В одном проекте Shake c я создал библиотеку stati c с именем libbuild3a.a

. Я хочу использовать ее в отдельном проекте Shake c, напрямую добавив его в исходные файлы. Я получаю следующую ошибку, когда он пытается скомпилировать main. c, который будет exe.

Командная строка: g cc - c src3b / main. c -Lsrc3b / lib -lbuild3a -o build3b / src3b / main.o -MMD -MF build3b / src3b / main.m Код выхода: 1 Stderr: src3b / main. c: 2: 10: фатальная ошибка: add.h: Нет такого файла или каталога #include

Вот проект Shake. Это тестовый проект, направленный на вызов c с haskell ffi.

build3b :: IO ()
build3b = shakeArgs shakeOptions{shakeFiles="build3b"} $ do
  let
    buildDir = "build3b"
    srcDir = "src3b"
  want [buildDir </> "run3b" <.> exe]

  buildDir </> "run3b" <.> exe %> \out -> do
        putInfo "============== entering exe creation ====================="

        --Do I need to load the static library?
        cs_main <- getDirectoryFiles "" [srcDir </>  "main.c", srcDir </> "lib" </> "libbuild3a.a"]
        need cs_main

        putInfo "showing main source file"
        mapM putInfo cs_main

        putInfo "starting compile of main.c main file"
        let
          os_main = [buildDir </> c -<.> "o" | c <- cs_main]
        need os_main
        mapM putInfo os_main

        --cmd_ "gcc -o" [out] os_main
        --cmd_ "gcc -o -Llib -lbuild3a" [out] os_main
        cmd_ "gcc -o -Lsrc3b/lib -lbuild3a" [out] os_main

  buildDir </> srcDir </>  "main.o" %> \out -> do
        putInfo $ "buildDir/main.o: " ++ show out
        let c = dropDirectory1 $ out -<.> "c"
        let m = out -<.> "m"
        cmd_ "gcc -c" [c] "-o" [out] "-MMD -MF" [m]
        --cmd_ "gcc -c" [c] "-Lsrc3b/lib -lbuild3a -o" [out] "-MMD -MF" [m]
        neededMakefileDependencies m

  {-I added this as shake complained about not having a rule for libbuild3a.o
    I tried to deconstruct the library useing `ar`. Got rid of the no rule failure,
    but did not help in finding add.h in main.c-}     
  buildDir </> "src3b" </> "lib" </> "libbuild3a.o" %> \out -> do
        putInfo $ "buildDir/lib/libbuild3a.o: " ++ show out
        let c = dropDirectory1 $ out

        libs <- getDirectoryFiles "" [srcDir </> "lib" </> "libbuild3a.a"]
        need libs
        --cmd_ "ar rcs" [out] os_tq84
        --[cmd_ "ar -xv l add.o answer.o" [out] l | l <- libs]
        cmd_ "ar -xv libbuild3a.a add.o answer.o" [out] libs

А вот и главный. c, пытающийся его использовать. Это будет exe.

#include <stdio.h>
#include <add.h>
#include <answer.h>

int main(int argc, char* argv[]) {

  setSummand(5);

  printf("5 + 7 = %d\n", add(7));

  printf("And the answer is: %d\n", answer());

  return 0;
}

Было бы лучше просто использовать исходные файлы и не беспокоиться о библиотеке .a. Или, может быть, мы ar разложим библиотеку на ее файлы .o? Я попробовал это в последнем правиле без эффекта.

1 Ответ

0 голосов
/ 16 марта 2020

Я решил проблему, связав библиотеку stati c с опциями gh c.

Проблема теперь в том, что main_exe не видит изменений в файле libsupply.a. Мне нужно выяснить, как это сделать, хотя вызов, который создает библиотеку

cmd_ "ar rcs" [out] co

, является последним выражением в правиле.

Вот новый источник:

build4 :: IO ()
build4 = shakeArgs shakeOptions{shakeFiles="build4"} $ do
  let buildDir = "build4"
      srcDir = "src4"
  want [srcDir </>  "libsupply.a"]
  want [buildDir </> "main_exe" <.> exe]

  buildDir </> "main_exe" <.> exe %> \out -> do

      cmd_
          "ghc"
          ("src4" </> "main.hs")
          "-isrc"
          "-Lsrc4"
          "-lsupply"
          "-outputdir"
          "build4"
          "-o"
          out


  srcDir </> "libsupply.a" %> \out -> do
    putInfo $ "in build4/libsupply.a: " ++ ( show out)
    cs <- getDirectoryFiles "" [srcDir </> "*.c"]
    need  cs

    let co = [buildDir </> c -<.> "o" | c <- cs]
    need co

    cmd_ "ar rcs" [out] co


  --build the .c files required for the library
  buildDir </> "//*.o" %> \out -> do
    putInfo $ "in build_dir </> //*.o: " ++ ( show out)
    let c = dropDirectory1 $ out -<.> "c"
    let m = out -<.> "m"
    cmd_ "gcc -c" [c] "-o" [out] "-MMD -MF" [m]
    neededMakefileDependencies m
...