2013-07-02 9 views
7

Pracuję nad pakietem bibliotecznym Haskell, który wymaga niestandardowych plików .dll i .lib w systemie Windows, aby porozmawiać z niektórymi interfejsami API systemu operacyjnego. Plik .lib jest połączony z biblioteką za pomocą pola extra-libraries, a biblioteka DLL jest instalowana w katalogu pakietów cabal pod numerem data-files.Statyczne .lib wymagane do kompilowania biblioteki jest również wymagane dla użytkowników biblioteki?

Z jakiegoś powodu (nie jestem ekspertem od linkowania w jakikolwiek sposób, ale to wydaje się dziwne) jeśli utworzę testowy plik wykonywalny, który używa mojego pakietu (w polu build-depends), chce on połączyć w tym samym. lib używane do kompilowania biblioteki - nawet jeśli jest to po prostu wywołanie funkcji bibliotecznych, a nie wszystko, co eksponuje .lib. Oczywiście potrzebuje dostępu do pliku .dll w czasie wykonywania, ale tego można się spodziewać. Również użycie .lib wydaje się dziwne.

Spodziewam się, że plik .lib będzie już połączony z plikiem .a wygenerowanym przez Cabal/GHC dla mojej biblioteki, kiedy jest zainstalowany. Czy tak nie jest? A jeśli tak, czy ktoś może wyjaśnić, dlaczego tak jest?

Odpowiedz

1

Wygląda na to, że chcesz częściowe połączenie (patrz: strona --relocatable na stronie podręcznika ld). Jak widzę ze źródeł, cabal wykorzystuje częściowe biblioteki łączące, kompilowane dla ghci. Od Distribution.Simple.GHC (buildLib funkcji):

whenVanillaLib False $ do 
    (arProg, _) <- requireProgram verbosity arProgram (withPrograms lbi) 
    Ar.createArLibArchive verbosity arProg 
    vanillaLibFilePath staticObjectFiles 

whenProfLib $ do 
    (arProg, _) <- requireProgram verbosity arProgram (withPrograms lbi) 
    Ar.createArLibArchive verbosity arProg 
    profileLibFilePath profObjectFiles 

whenGHCiLib $ do 
    (ldProg, _) <- requireProgram verbosity ldProgram (withPrograms lbi) 
    Ld.combineObjectFiles verbosity ldProg 
    ghciLibFilePath ghciObjFiles 

whenSharedLib False $ 
    runGhcProg ghcSharedLinkArgs 

Widać, że dla wanilii i bibliotek profili cabal po prostu wywołuje ar narzędziowego (patrz createArLibArchive). Dla ghci wywołuje ld z flagą -r (która jest skrótem dla --relocatable) (patrz combineObjectFiles).

Tak więc, cabal w rzeczywistości nie robi żadnych powiązań dla bibliotek waniliowych, po prostu łączy pliki obiektów. Aktualnie cabal nie może wiedzieć, czy ostateczna aplikacja użyje dowolnego symbolu z twojego extra-lib, więc zachowanie wydaje się rozsądne.

+0

Czy istnieje sposób zmuszenia go do użycia 'ld -r' zamiast' ar' dla bibliotek wanilii? Próbowałem dodać 'ld-options: -r', ale wydaje się, że nic nie robi (prawdopodobnie dlatego, że' ld' nie jest używany?) –

+0

@TomSavage Nie, myślę, że to niemożliwe. Ale nie jestem ekspertem od kabały. – Yuras

Powiązane problemy