1

今まで私は次のコードを持っていました:

shakeArgsWith opts additionalFlags $ \flags targets -> return $ Just $ do
    ...
    -- Get target arch from command line flags
    let givenArch = listToMaybe [v | AFlag v <- flags]
    let arch = fromMaybe defArch givenArch
    ...
    -- Set the main target
    let outName = masterOutName projType toolchain projName

    let mainTgt = (case projType of
                    Binary _ -> "bin"
                    Archive  -> "lib")
                  </> prettyShowArch arch
                  </> show variant
                  </> outName

    -- Set the build directory for the current run
    let buildDir = bldDir </> show toolchain </> prettyShowArch arch </> show variant
    ...
    mainTgt %> \out -> do ...
    ...
    buildDir <//> "*.o" %> \out -> do ...
    ...

つまり、解析中のコマンド ライン フラグに従って作成されたルールの名前です (それらには arch 変数が含まれていました)。

したがって、私が与えた場合、ディレクトリshake --arch=x64にメインターゲットを構築し、それに応じbin/x64/Releaseてフォルダーに中間ビルドファイルを構築していましたtmp/x64/Release

しかし、コマンド ライン フラグを使用する代わりに、ルール名を作成するために使用される共有アーチ変数を、コマンドの出力に従って入力する必要があります。たとえば、最上位レベルのアクションを定義できる場合は、次のようになります。

Stdout sout <- quietly $ cmd (EchoStdout False) (EchoStderr False) "gcc -dumpmachine" :: Action (Stdout String)
let foundArch = show (gccTripletToArch sout)

mainTgtとの名前を作成するときに、アーチの代わりに変数 foundArch を使用しますbuildDir。関数で作成できる唯一の最上位ルールでさえ をaction返すため、明らかにこれは実行できませんRule ()。代わりに何ができますか?

4

1 に答える 1

1

私はあなたができるはずだと思います:

shakeArgsWith opts additionalFlags $ \flags targets -> do
     Stdout sout <- cmd (EchoStdout False) (EchoStderr False) "gcc -dumpmachine"
     let arch = show (gccTripletToArch sout)
     return $ Just $ do
         let buildDir = bldDir </> show toolchain </> prettyShowArch arch </> show variant
         ...
         buildDir <//> "*.o" %> \out -> do ...

Shake のターゲット パターンは静的に既知である必要があります。これにより、迅速な再構築に関していくつかの重要なプロパティが保証されます (1 か所の変更が予測可能な効果を持つことを保証できます)。ただし、コマンドを実行して、ビルド スクリプトを作成し、それらを焼き込む前に、アーチ、コンパイラのバージョンなどを確認することができます。

もう 1 つの観点は、アーキテクチャに基づいてビルド システムを動的に生成することです。Shake を Haskell EDSL として使用することは、特に問題はありません。おそらく、以前はコマンド ラインでそれを行っていました。

于 2015-11-13T13:23:46.737 に答える