You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链接器报ltc E108错误:符号在fsdata.o与fs.o中重复定义

解决链接器重复定义符号问题

链接器错误信息

ltc E108: multiple definitions of symbol "file__img_sics_gif" in both "fsdata.o" and "fs.o"
ltc E108: multiple definitions of symbol "file__404_html" in both "fsdata.o" and "fs.o"
ltc E108: multiple definitions of symbol "file__index_html" in both "fsdata.o" and "fs.o"
make: *** [makefile:95: Ethernet_1_KIT_TC397_TFT.elf] Error 1

问题背景

重复定义的符号是fsdata.c中定义的结构体数组:

const struct fsdata_file file__img_sics_gif[] = {{
file_NULL,
data__img_sics_gif,
data__img_sics_gif + 16,
sizeof(data__img_sics_gif) - 16,
FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT,
}};

const struct fsdata_file file__404_html[] = {{
file__img_sics_gif,
data__404_html,
data__404_html + 12,
sizeof(data__404_html) - 12,
FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT,
}};

const struct fsdata_file file__index_html[] = {{
file__404_html,
data__index_html,
data__index_html + 12,
sizeof(data__index_html) - 12,
FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT,
}};

#define FS_ROOT file__index_html
#define FS_NUMFILES 3

当前在fs.c中直接包含了fsdata.c文件,通过宏FS_ROOT访问这些结构体,而fsdata_file结构体的定义位于fs.h:

struct fsdata_file {
  const struct fsdata_file *next;
  const unsigned char *name;
  const unsigned char *data;
  int len;
  u8_t flags;
  #if HTTPD_PRECALCULATED_CHECKSUM
  u16_t chksum_count;
  const struct fsdata_chksum *chksum;
  #endif /* HTTPD_PRECALCULATED_CHECKSUM */
}; 

核心原因

fsdata.c被单独编译生成了fsdata.o,同时fs.c又直接包含fsdata.c,导致编译fs.c时这些结构体被再次定义,最终两个目标文件中存在完全相同的符号,链接时触发冲突。

解决方法

方法1:改用头文件声明(推荐)

这是C语言项目解决符号重复定义的标准做法:

  1. 创建fsdata.h头文件,在里面用extern声明符号并保留宏定义:
#ifndef FSDATA_H
#define FSDATA_H

#include "fs.h"

extern const struct fsdata_file file__img_sics_gif[];
extern const struct fsdata_file file__404_html[];
extern const struct fsdata_file file__index_html[];

#define FS_ROOT file__index_html
#define FS_NUMFILES 3

#endif /* FSDATA_H */
  1. 修改fs.c,将原来的#include "fsdata.c"替换为#include "fsdata.h"
  2. (可选)在fsdata.c开头添加#include "fsdata.h",确保声明与定义的一致性

这样编译时,fsdata.o包含符号的唯一定义,fs.o通过头文件的extern声明引用这些符号,不会出现重复定义。

方法2:禁止单独编译fsdata.c

如果不想调整头文件结构,可以修改Makefile,移除fsdata.c的编译规则:

  • 找到Makefile中目标文件列表(通常是OBJS变量),删除其中的fsdata.o
  • 确保只有fs.c包含fsdata.c,这样结构体只会被编译一次,不会生成重复的目标文件

这种方式不够规范,仅适合临时快速修复。

方法3:添加静态修饰(不推荐)

给fsdata.c中的结构体定义加上static关键字:

static const struct fsdata_file file__img_sics_gif[] = {{...}};

这样符号作用域被限制在单个目标文件内,链接时不会冲突,但会导致fsdata.o和fs.o中各存一份相同的数据,浪费内存,因此不推荐。

内容的提问来源于stack exchange,提问作者Rana Zeeshan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:03:21