我有一个大问题,我有一个程序,它会扫描您的所有电脑,找到重复的文件(相同内容的 int 文件)并创建硬链接而不是该文件。我使用 SHA256 计算控制和以与其他文件进行比较。我的程序由6个文件组成:Cleaner.c Cleaner.h SHA256.c SHA256.h HashMap.c HashMap.h main.c。当我尝试编译它时遇到问题。我有错误:
1 warning generated.
gcc -Wall -Wextra -o program main.o Cleaner.o HashMap.o SHA256.o
duplicate symbol '_k' in:
main.o
Cleaner.o
duplicate symbol '_k' in:
main.o
HashMap.o
duplicate symbol '_k' in:
main.o
SHA256.o
ld: 3 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我尝试使用Makefile。 这是Makefile:
CC = gcc
CFLAGS = -Wall -Wextra
all: program
program: main.o Cleaner.o HashMap.o SHA256.o
$(CC) $(CFLAGS) -o program main.o Cleaner.o HashMap.o SHA256.o
main.o: main.c Cleaner.h HashMap.h SHA256.h
$(CC) $(CFLAGS) -c main.c
Cleaner.o: Cleaner.c Cleaner.h
$(CC) $(CFLAGS) -c Cleaner.c
HashMap.o: HashMap.c HashMap.h
$(CC) $(CFLAGS) -c HashMap.c
SHA256.o: SHA256.c SHA256.h
$(CC) $(CFLAGS) -c SHA256.c
clean:
rm -f program *.o
我不知道这个符号“_k”在哪里,也许在SHA256.h里,有
typedef struct
{
uchar data[64];
uint datalen;
uint bitlen[2];
uint state[8];
} SHA256_CTX;
uint k[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
void SHA256Transform(SHA256_CTX *ctx, uchar data[]);
void SHA256Init(SHA256_CTX *ctx);
void SHA256Update(SHA256_CTX *ctx, uchar data[], uint len);
void SHA256Final(SHA256_CTX *ctx, uchar hash[]);
char *SHA256(char *data, long strlen);
我从这个网站获取了 SHA256 的实现 https://www.programmingalgorithms.com/algorithm/sha256/c/
我尝试使用 GCC 但出现另一个错误:
black_daddy@air-aleksandr Куровая работа ОСИСП % gcc -o *.c
SHA256.c:120:21: warning: passing 'char *' to parameter of type 'unsigned char *' converts between pointers to integer types where one is of the unique plain 'char' type and the other is not [-Wpointer-sign]
SHA256Update(&ctx, data, strlen);
^~~~
SHA256.c:59:42: note: passing argument to parameter 'data' here
void SHA256Update(SHA256_CTX *ctx, uchar data[], uint len)
^
1 warning generated.
Undefined symbols for architecture arm64:
"_readFilesInDirectory", referenced from:
_main in main-d6f236.o
ld: symbol(s) not found for architecture arm64
我认为这是由于错误链接造成的,因为创建了 obj 文件。
我认为这是由于错误链接造成的,因为创建了 obj 文件。
该问题是在链接时“检测到”的,但它是由不正确的代码“引起”的。 C 语言规范的每个版本都有此规定或与其基本等效的规定:
如果在外部链接中使用了声明的标识符
表达式(除了作为 sizeof
_Alignof
运算符,其结果是整数常量),位于 整个程序应该只有一个外部定义 标识符;否则,不得超过一个。
(C17 6.9/5)...
uint k[64] = {
[...]
}
... 所提供的标头中提供了
k
的声明以及外部链接这也是一个定义
,在每个直接或间接作为该标头的源文件中。因此,如果程序的多个翻译单元包含该标头,并且至少有一个访问
#include
,则该程序就会违反语言规范。由此产生的行为是未定义的。根据编译器发出的诊断信息,您有四个不同的翻译单元k
标头,并且显然其中至少一个访问#include
(可能通过声明的函数之一)。从历史上看,一些 C 实现已经接受了存在此类问题的程序。您可以通过将 k
添加到您的编译和(特别是)链接标志来诱导您这样做。但是,更好的方法是通过将 -fcommon
的定义移动到 C 源文件之一,并更改标头以仅提供不带任何初始化程序的
k
声明来修复代码。