Встряхнуть для кросс-компиляции?
У меня есть проект, который строит два набора целей. Одним из них является прошивка для различных версий портативных устройств, которая в конечном итоге создает файл.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