いくつかの条件が満たされた場合にのみリリースにリンクされる、いくつかの異なるライブラリ/オブジェクトを含むモジュラー C プロジェクトがあります。このプロジェクトは PowerPC 用の GCC 3.4.4 でビルドされています。
したがって、私のプロジェクト全体に、他のモジュールの関数を使用する C ファイルがいくつかあります (これらのモジュールは必ずしもビルドに追加されるわけではありません)。したがって、これらの関数は extern として宣言されます。
リリースに応じて、関数自体を含むモジュールがリンクされているかどうかが異なります。未定義の参照を避けるために、これらの関数はアセンブラ マクロで弱いものとして宣言されます。
私はこれを例で示しようとしています:
ModuleA.c (コアモジュール)
extern void bar(void);
void foo(void)
{
// Do some Stuff
bar();
}
ModuleB.c (オプションモジュール)
void bar(void)
{
// Do some stuff
}
ModuleB は常に ModuleA にリンクされているわけではなく、一部の特定のリリース ビルドでのみリンクされています。したがって、3 番目の C ファイルがあります。
weakfuncs.c (コアモジュール)
#define WEAK(x,y) __asm__(".weak " #x "\n.set " #x "," #y "\n");
void empty_function(void);
__asm__("empty_function:\nblr\n");
WEAK(bar,empty_function)
このマクロを使用すると、プロジェクトは常にビルドされます (ModuleB がリンクされている場合は ModuleB から呼び出され、ModuleB がリンクbar()
されていない場合は.bar()
empty_function()
プロジェクト全体にこれらのケースがたくさんあるので、私の前任者はこれらすべての機能を に集めていましたweakfuncs.c
。
これまでのところ、これは私が再利用しているレガシーコードでした
ここで、MinGW (GCC 4.8.1) を使用して Windows 用にすべてをコンパイルしたいと思います。私の問題は、コンパイラがアセンブラ ディレクティブに問題があるように見えることです。
__asm__("empty_function:\nblr\n");
まったく機能していません (彼はコマンドを知りblr
ません) が、次のように C で空の関数を実装できるため、これは問題ではありません。
void empty_function(void)
{
return;
}
WEAK マクロ自体
#define WEAK(x,y) __asm__(".weak " #x "\n.set " #x "," #y "\n");
問題なくコンパイルされますが、効果はありません。つまり、リンクされていない関数は、WEAKマクロを実行したとしても、「未定義の参照」を引き起こします。
これで、関数に次のように属性 weak を与える方法が gcc にあることがわかりました。
extern void bar() __attribute__((weak));
これは実際には機能しますが、適応が必要な関数がたくさんあるのでweakfuncs.c
、マクロを使用してそれを行うことをお勧めします。
プレース全体ですべての関数宣言を変更せずに、アセンブラー ディレクティブまたは C でそうする方法はありますか?