Выбор компилятора C в пакете cabal

Я решил добавить несколько флагов, чтобы управлять тем, как скомпилирован исходный файл C (например, use-clang, use-intel и т.д.).

      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

Вопрос: какие параметры в файле descritpion необходимо изменить для изменения компилятора C? Я нашел только CC-Options.

Ответ 1

По-видимому, нет никакого способа указать это в файле .cabal; единственное, что, как нам кажется, в настоящий момент было бы даже отдаленно полезным, - это --with-<prog>=path.

Я предлагаю вам попробовать подать билет против Cabal на trac.

Ответ 2

Нет простого пути, но это возможно.

Предполагая, что вы используете Distribution.Simple, вам в основном нужно добавить пользовательский крючок на этап сборки.

Все изменения должны появиться в Setup.hs:

Измените main, чтобы использовать крюк сборки, например:

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

Далее вам нужен крюк сборки. Вероятно, это выглядит примерно так:

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

Вышеприведенный код, вероятно, нуждается в распаковке. Предоставленные предложения в основном касаются распаковки необходимых полей данных из структур, переданных на крючок сборки. Обратите внимание, что вы можете создавать пользовательские строфы в своем foo.cabal. Я предоставил код для поддержки строфы что-то вроде:

x-cc-name: icc

В качестве средства для указания вашего компилятора. Выбрав все исходные файлы, вы сопоставляете их с помощью функции для компиляции одного файла (NB: в некоторых случаях это недооптимально, например, те компиляторы, которые могут эффективно скомпилировать несколько исходных файлов для создания одного объекта вывода и выгоды от крупномасштабных оптимизаций, но мы оставим это в стороне на данный момент).

В конце концов, поскольку мы теперь скомпилировали код C/С++, удалите его из структур построения, прежде чем передавать все на установочный крюк по умолчанию.

Извините, что это скорее "HOWTO", чем консервированный ответ, но он должен помочь вам разобраться.

Я должен упомянуть, что код не проверен. Я адаптировал его из некоторой работы, которую я делал в системе сборки wxHaskell, поэтому я знаю, что идея работает нормально. API Cabal на самом деле довольно хорошо документирован - он страдает в основном от некоторой нестабильности в некоторых из этих областей.