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.
Vero. C'è un [numero # 1325 su github] (https://github.com/haskell/cabal/issues/1325) :) – ony