Встряхнуть для кросс-компиляции?

У меня есть проект, который строит два набора целей. Одним из них является прошивка для различных версий портативных устройств, которая в конечном итоге создает файл.dfu для каждого устройства. Это использует цепочку составления руки. Другой набор - это эмуляторы для тех же устройств, которые компилируют код для платформы сборки (ну, как правило, в любом случае). Makefile, которые я унаследовал, не работают хорошо ни в одной среде, где cc!= Gcc из-за проблем с передачей компилятора в рекурсивные make.

Я думаю о переписывании файлов сборки в Shake, но мне было интересно, насколько хорошо он справляется с желанием сделать "make release", который затем компилирует один и тот же набор исходных файлов несколько раз с разными компиляторами или флагами для генерации различных типов двоичных файлов., Не проблема, с которой я сталкивался раньше, и, основываясь на моих поисках в Google, многие люди не говорили об этом публично.

2 ответа

Решение

Я не знаю людей, использующих Shake для кросс-компиляции (хотя я предполагаю, что это происходит), но многие люди создают разные конфигурации с помощью одного сценария Shake, например, debug/profile/release, и для этого требуются примерно одинаковые операции. Обычный подход заключается в размещении выходных файлов в разных каталогах и определении разных правил (или одного и того же правила, но параметризованных) на основе выходного каталога. В качестве одного примера:

"release/arm//*.obj" *> \out -> command "arm-cc" ["source-file.c","-o",out]
"release/x86//*.obj" *> \out -> command "gcc" ["source-file.c","-o",out]

В качестве альтернативы вы можете иметь одно и то же правило для каждого и просто переключать компилятор на основе каталога:

"release//*.obj" *> \out ->
    let cc = if takeDirectory1 $ dropDirectory1 out == "arm" then "arm-cc else "gcc"
    command cc ["source-file.c","-o",out]

То, что работает лучше всего, обычно зависит, если arm и x86 в основном идентичны, но переключают компилятор, или просто очень разные вещи.

В конце вы просто позвоните want ["release/arm/install.tar.gz","release/x86/install.tar.gz"] Shake рекурсивно создаст оба релиза одновременно.

Может быть, посмотрите на Shake-language-c. В настоящее время он используется с мобильными и веб-инструментами кросс-компиляции, но он должен быть простым для взаимодействия с другими инструментами.

Вот пример для компиляции статической библиотеки для устройства iOS и симулятора:

import Control.Applicative
import Control.Arrow
import Control.Monad
import Development.Shake
import Development.Shake.FilePath
import Development.Shake.Language.C
import qualified Development.Shake.Language.C.Target.OSX as OSX

main :: IO ()
main = shakeArgs shakeOptions { shakeFiles = "build/" } $ do
  let -- Target the device and simulator
      targets = map (uncurry OSX.target)
                    [ (OSX.iPhoneOS, (Arm Armv7s))
                    , (OSX.iPhoneSimulator, (X86 I386)) ]

  -- Declare static library for each target
  libs <- forM targets $ \target -> do
    let toolChain = OSX.toolChain
                    <$> OSX.getSDKRoot
                    <*> (maximum <$> OSX.getPlatformVersions (targetPlatform target))
                    <*> pure target
    staticLibrary toolChain
          -- Unique name for each library target
          ("build" </> toBuildPrefix target </> "libexample.a")
          (return $ 
               append compilerFlags [(Just Cpp, ["-std=c++11"])]
           >>> append compilerFlags [(Nothing, ["-O3"])]
           >>> append userIncludes ["include"] )
          (getDirectoryFiles "" ["src//*.cpp"])

  -- Build them all
  want libs
Другие вопросы по тегам