少数のファイル (.c および .h) しかない比較的小さなプロジェクトがあります。私は複数の包含エラーと戦ってきました(と思います)。そこで、必要な他の各ヘッダー ファイルを含む master.h ヘッダー ファイルを作成しました。すべてのヘッダー ファイルには、
#ifndef _MY_HEADER
#define _MY_HEADER
… Header body
#endif
複数の包含を防ぐためのガード。私の各ファイルには、上部に master.h ファイルが含まれています。これが私がこれがどのように機能することを期待するかです。
- コンパイルされた最初のファイルには、#include "master.h" が表示されます。
- このファイルが処理されるのはこれが初めてであるため、__MASTER はまだ定義されていないため、ファイルが処理されます。
- コンパイラは次のヘッダー ファイルをインクルードします。同様に、それはまだ処理されていないため、コンパイラはそれを処理し、定義され、再度処理されることはありません。
- これは、すべてのファイルが処理され、再処理されないように定義されるまで、master.h 内のすべてのヘッダー ファイルに対して続行されます。
- master.h ファイルについても同様です。一度処理されて完了すると、ガードにより再度処理されることはありません。
これは複数の包含を防ぐべきではありませんか?
ここにエラーがあります。
Building target: My_Project_Bootloader.axf
Invoking: GNU ARM C Linker
arm-none-eabi-gcc -g3 -gdwarf-2 -mcpu=cortex-m3 -mthumb -T "C:/Users/Greg/SimplicityStudio/v4_workspace/My_Project_Bootloader/GNU ARM v4.9.3 - Debug/My_Project_Bootloader_custom.ld" -nostdlib -L"C:\GCC_STUFF" --specs=nosys.specs -Xlinker --gc-sections -Xlinker -Map="My_Project_Bootloader.map" -lm -lgcc -lc -o My_Project_Bootloader.axf "./Source/aeabi_memset-thumb.o" "./Source/crt0.o" "./Source/em_emu.o" "./Source/functions.o" "./Source/main.o" "./Source/startup_efm32jg1b.o" "./Source/interrupts.o"
./Source/main.o:(.rodata.const_ModBusIDReg+0x0): multiple definition of `const_ModBusIDReg'
./Source/functions.o:(.rodata.const_ModBusIDReg+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make: *** [My_Project_Bootloader.axf] Error 1
関係ないことが判明したため、この投稿の情報の一部を編集/削除しました。リンカーが抱えていた「複数の定義」の問題は、実際の「複数の定義」や変数の包含によるものではないようです。代わりに、変数 (この場合はフラッシュ内の const) の宣言と定義が同時に行われたためであるかのように見えます。宣言をヘッダー ファイルに分割し、実際の定義または割り当てを .c ファイルに分割すると、問題はなくなりました。問題の「変数」の 1 つに対する修正の例を次に示します。ここで、変数の宣言と定義の側面にさらに注意を払います。使用したツールは GCC です。コメントありがとうございます。
// boot.h
// declare const array
const unsigned char const_ModBusIDReg[7][48];
// boot.c
#include boot.h
// define const array
const unsigned char const_ModBusIDReg[7][48] =
{
"String1", // reg00
"String2", // reg01
"String3", // reg02
"String4", // reg03
"String5", // reg04
"String6", // reg05
"String7" // reg06
};