2010-03-27 19 views
11

Ho deciso di aggiungere alcuni flag per controllare il modo in cui il file sorgente C è compilato (ad esempio, use-clang, use-intel ecc.).Selezione del compilatore C nel pacchetto cabal

 
     C-Sources: c_lib/tiger.c 
     Include-Dirs: c_lib 
     Install-Includes: tiger.h 

     if flag(debug) 
      GHC-Options: -debug -Wall -fno-warn-orphans 
      CPP-Options: -DDEBUG 
      CC-Options: -DDEBUG -g 
     else 
      GHC-Options: -Wall -fno-warn-orphans

La domanda è: quali opzioni nel file descrittpion devono essere modificate per modificare il compilatore C? Ho trovato solo CC-Options.

risposta

1

Sembra che non ci sia un modo per specificarlo in un file .cabal; l'unica cosa che sembra avere al momento che sarebbe anche lontanamente utile qui è --with-<prog>=path.

Ti suggerisco di provare a presentare un biglietto contro Cabal su trac.

+1

Vero. C'è un [numero # 1325 su github] (https://github.com/haskell/cabal/issues/1325) :) – ony

0

4.10.1. Replacing the program for one or more phases

-pgmc cmd
              Usa cmd come il compilatore C.

Questo funziona per ghc --make, ma non sono sicuro di come ottenere Cabal per applicarlo alla compilazione del file C.

+0

Provato - nulla è cambiato. Se si specifica "-fvia-C" vengono visualizzati errori previsti durante la compilazione dei file Haskell, quindi questa opzione non viene filtrata. Sembra che Cabal stia usando la propria sequenza per costruire file ".c". – ony

7

Non esiste un modo semplice, ma è possibile.

Supponendo che si stia utilizzando Distribution.Simple, è fondamentalmente necessario aggiungere un hook utente alla fase di creazione.

Tutte le seguenti modifiche deve necessariamente apparire in Setup.hs:

principale modifica per utilizzare un gancio di generazione, qualcosa di simile a:

main :: IO() 
main = defaultMainWithHooks simpleUserHooks { buildHook = myBuildHook } 

Dopodiché è necessario un gancio build. Probabilmente sarà simile al seguente:

myBuildHook pkg_descr local_bld_info user_hooks bld_flags = 
    do 
    let lib  = fromJust (library pkg_descr) 
     lib_bi = libBuildInfo lib 
     custom_bi = customFieldsBI lib_bi 
     cpp_name = fromJust (lookup "x-cc-name" custom_bi) 
     c_srcs = cSources lib_bi 
     cc_opts = ccOptions lib_bi 
     inc_dirs = includeDirs lib_bi 
     lib_dirs = extraLibDirs lib_bi 
     bld_dir = buildDir local_bld_info 
    -- Compile C/C++ sources 
    putStrLn "invoking my compile phase" 
    objs <- mapM (compileCxx cpp_name cc_opts inc_dirs bld_dir) c_srcs 
    -- Remove C/C++ source code from the hooked build (don't change libs) 
    let lib_bi' = lib_bi { cSources = [] } 
     lib'  = lib { libBuildInfo = lib_bi' } 
     pkg_descr' = pkg_descr { library = Just lib' } 
    -- The following line invokes the standard build behaviour 
    putStrLn "Invoke default build hook" 
    bh <- buildHook simpleUserHooks pkg_descr' local_bld_info user_hooks bld_flags 
    return bh 

Il codice sopra probabilmente ha bisogno di un po 'di disimballaggio. Le clausole let sono fondamentalmente sullo spacchettamento dei campi dati richiesti dalle strutture passate all'hook di build. Nota che puoi creare stanze personalizzate nel tuo foo.cabal. Ho fornito il codice per supportare una stanza come:

x-cc-name: icc 

Come mezzo per specificare il compilatore. Dopo aver estratto tutti i file sorgente, si esegue il mapping su di essi utilizzando una funzione per compilare un singolo file (NB: in alcuni casi questo non è ottimale, ad esempio quei compilatori che possono compilare in modo efficiente più file sorgente per produrre un output di un singolo oggetto e beneficiare da ottimizzazioni su larga scala, ma lasceremo da parte per ora).

Infine, come abbiamo ora compilato il codice C/C++, rimuoverlo dalle strutture di compilazione prima di passare tutto al build di default.

Mi dispiace che questo sia più di un "HOWTO" di una risposta in scatola, ma dovrebbe aiutarti ad andare avanti.

Devo dire che il codice non è stato verificato. L'ho adattato da qualche lavoro che ho fatto sul sistema di compilazione wxHaskell, quindi so che l'idea funziona correttamente.L'API Cabal è in realtà piuttosto ben documentata - soffre principalmente di essere un po 'instabile attorno ad alcune di queste aree.

Problemi correlati