2

マニュアルには私が間違っていることを実際に書かれているのではないかと思いますが、解決策は実際にはわかりません。この問題は、ビルドする.cファイルと.oファイルが同じディレクトリになく、.cファイルがその場で生成する必要のある.hファイルに自動的に依存している場合に発生します。この問題は、.cファイルと.hファイルの間に依存関係を手動で設定することで解決できる可能性がありますが、それは避けたいと思います。

私は次のディレクトリ構造を持っています:

weird/
    Jamfile
    b.c
    src/
        a.c
        c.c

src/acファイルは次のようになります。

#include "src/a.h"

int main(int argc, char *argv[])
{
    return 0;
}

bcファイルは次のようになります。

#include "src/b.h"

int main(int argc, char *argv[])
{
    return 0;
}

src/ccファイルは次のようになります。

#include "c.h"

int main(int argc, char *argv[])
{
    return 0;
}

Jamfileは次のとおりです。

rule CreateHeader
{
    Clean clean : $(1) ;
}

actions CreateHeader
{
    echo "int x = 10;" > $(1)
}

Object a.o : src/a.c ;
Object b.o : b.c ;
Object c.o : src/c.c ;

CreateHeader src/a.h ;
CreateHeader src/b.h ;
CreateHeader src/c.h ;

次のコマンドは、boとsrc/bhを正しく作成します。

jam b.o

次のコマンドはsrc/ahを作成しますが、GCCはaoの作成に失敗します。その理由は、acの#includeがsrc / ahに言及しているのに対し、実際には単にahを参照していることは明らかです。

jam a.o

次のコマンドは完全に失敗し、chも作成しません。その理由はおそらく、Jamがccを分析すると、src / chではなくchへの依存関係が生成され、Jamfileにはchを生成するためのルールがないためです。

jam c.o

coを要求する前にsrc/chを生成するように明示的に要求すると、このコマンドは正しくコンパイルされます。

jam src/c.h
jam c.o

私の意見では、jam src/chは必要ないはずです。ここで何が問題になっていますか?詳細については、特にヘッダーファイルスキャンのセクションで、Jamのマニュアルを確認してください。

答えを受け入れた後に追加

受け入れられた回答の作成者によって提案された構成を少し実験し続けました。結果をここに投稿します。この設定では、次のように入力できます。

jam app

そして、アプリケーションはbin/appの下にリンクされます。残念ながら、LOCATE_TARGETを設定するときにUNIXパスを使用する必要がありましたが、これは必ずしも良い方法ではないことを理解しています。

ディレクトリ構造:

project/
    Jamfile
    src/
        main.c
    gen/
    bin/
        obj/

ファイルJamfile:

SubDir TOP ;

rule CreateHeader
{
    MakeLocate $(1) : $(LOCATE_SOURCE) ;
    Clean clean : $(1) ;
}

actions CreateHeader
{
    BUILD_DATE=`date`
    echo "char build_date[] = \"$BUILD_DATE\";" > $(1)
}

SEARCH_SOURCE = src ;
LOCATE_TARGET = bin/obj ;
SubDirHdrs gen ;
Object main.o : main.c ;

LOCATE_TARGET = bin ;
MainFromObjects app : main.o ;

LOCATE_SOURCE = gen ;
CreateHeader info.h ;

ファイルsrc/main.c

src/main.c
#include <stdio.h>
#include "info.h"

int main(int argc, char *argv[])
{
    printf("Program built with Jam on %s.\n", build_date);

    return 0;
}
4

1 に答える 1

2

すべての #include ディレクティブを変更してパスを省略し (つまり、「#include "ah" など)、Jamfile を次のように変更すると、問題が解決します。

SubDir TOP ;

SEARCH_SOURCE += [ FDirName $(SUBDIR) src ] ;
LOCATE_SOURCE = [ FDirName $(SUBDIR) src ] ;

rule CreateHeader
{
    MakeLocate $(1) : $(LOCATE_SOURCE) ;
    Clean clean : $(1) ;
}

actions CreateHeader
{
    echo "int x = 10;" > $(1)
}

Object a.o : a.c ;
Object b.o : b.c ;
Object c.o : c.c ;

CreateHeader a.h ;
CreateHeader b.h ;
CreateHeader c.h ;

詳細は次のとおりです。

  • SubDir は常に Jamfile で呼び出す必要があります。ここで使用される SUBDIR、SEARCH_SOURCE、LOCATE_SOURCE など、いくつかの役立つ (場合によっては必要な) 変数を設定します。
  • 「src」サブディレクトリを SEARCH_SOURCE に追加すると、オブジェクト ルール呼び出しでソース ファイルの「src/」部分を省略できます。SEARCH_SOURCE もインクルード ディレクトリに自動的に追加されるため、 #include ディレクトリを短縮できます。
  • LOCATE_SOURCE は、生成されたソース ファイル (生成された yacc ソースとヘッダーなど) が配置されるディレクトリです。一貫性を保つために、CreateHeader はこの変数を使用します。これにより、CreateHeader の呼び出しで「src/」の部分を省略できる (また、省略しなければならない) ことに注意してください。

したがって、これらの変更の一般的な目的は、Jamfile で使用されるターゲット名から「src/」の部分を省略することです。一般に、Jamfiles のディレクトリ コンポーネントを省略することをお勧めします (代わりに、明確化のために grist を使用します)。Jam が「src/ah」と「ah」という名前のターゲットを動作させる方法は、前者が「.」にあると見なされていても、異なるターゲットであることに注意することが重要です。後者は "./src" にあります (たとえば、オンターゲットの SEARCH または LOCATE 変数によって)。あなたが与えたファイルで、Jam のヘッダー スキャンの結果は次のインクルード依存関係になります (これらはターゲット名です)。

src/a.c : src/a.h
b.c     : src/b.h
src/c.c : c.h

これにより、ジャミング「co」が失敗する理由が明らかになります。生成されると宣言したヘッダーのターゲット名が「src/ch」であるため、ターゲット「ch」は不明です。したがって、jam はインクルードの依存関係を無視します。「jam ao」が失敗した理由は、あなたが疑ったものです。

私が提案する変更には、ソース ファイルの #include ディレクティブを調整する必要がありますが、これは実際のユース ケースでは望ましくない/不可能な場合があります。状況はまだ救われるでしょう。たとえば、Jamfile を提案どおりに変更できますが、CreateHeader ルールを拡張します。

rule CreateHeader
{
    MakeLocate $(1) : $(LOCATE_SOURCE) ;
    Clean clean : $(1) ;
    Depends src/$(1) : $(1) ;
    NotFile src/$(1) ;
}

これは明らかにちょっとしたハックです。これは、ターゲット "src/ah" と友人を疑似ターゲットとして定義し、それぞれ対応する実際のターゲット ("ah" など) に依存します。このようにして、Jam のヘッダー スキャンは、「src/」プレフィックスがあるかどうかに関係なく、既知のターゲットになります。

ただし、ハックの少ない解決策は、インクルード関係を明示的に宣言することです。

Includes a.c : a.h ;
Includes b.c : b.h ;
于 2012-10-25T10:28:02.347 に答える