首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

生成程序时出现奇怪的链接器错误:‘多重定义’`fnames';src/main.o:(.data.rel.local+0x0):在此首次定义‘

这个错误是链接器错误,提示了一个多重定义的问题。具体来说,错误信息中提到了一个变量名为fnames的多重定义。

在解决这个问题之前,我们需要了解一下链接器的作用和工作原理。链接器是编译器的一部分,它的主要任务是将多个目标文件(编译后的文件)合并成一个可执行文件。在这个过程中,链接器会检查是否存在重复定义的符号(变量、函数等),如果存在多个定义,就会报错。

针对这个错误,我们可以采取以下几个步骤来解决:

  1. 检查代码中是否存在重复定义的变量fnames。在多个源文件中定义同名的全局变量会导致链接器错误。确保只在一个地方定义了该变量,并且在其他地方使用时使用extern关键字进行声明。
  2. 检查是否在头文件中定义了全局变量fnames,并且在多个源文件中包含了该头文件。如果是这种情况,可以考虑将全局变量的定义放在一个源文件中,并在其他源文件中使用extern关键字进行声明。
  3. 检查是否在多个源文件中包含了同一个源文件,或者在多个地方包含了同一个头文件。这样会导致同一个变量被多次定义,从而引发链接器错误。确保每个源文件和头文件只被包含一次。
  4. 如果以上步骤都没有解决问题,可以尝试使用命名空间来避免变量名冲突。将变量fnames放在一个命名空间中,确保不同源文件中的同名变量位于不同的命名空间中。

总结一下,链接器错误多重定义'fnames'通常是由于代码中存在重复定义的变量引起的。通过检查代码中的变量定义和声明,以及源文件和头文件的包含关系,可以解决这个问题。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云函数计算(Serverless):https://cloud.tencent.com/product/scf
  • 腾讯云容器服务(TKE):https://cloud.tencent.com/product/tke
  • 腾讯云数据库(TencentDB):https://cloud.tencent.com/product/cdb
  • 腾讯云CDN加速(CDN):https://cloud.tencent.com/product/cdn
  • 腾讯云人工智能(AI):https://cloud.tencent.com/product/ai
  • 腾讯云物联网(IoT):https://cloud.tencent.com/product/iotexplorer
  • 腾讯云移动开发(移动开发平台):https://cloud.tencent.com/product/mwp
  • 腾讯云对象存储(COS):https://cloud.tencent.com/product/cos
  • 腾讯云区块链(BCS):https://cloud.tencent.com/product/bcs
  • 腾讯云虚拟专用网络(VPC):https://cloud.tencent.com/product/vpc
  • 腾讯云安全产品(云安全中心):https://cloud.tencent.com/product/ssc
  • 腾讯云音视频处理(云点播):https://cloud.tencent.com/product/vod
  • 腾讯云元宇宙(QCloud XR):https://cloud.tencent.com/product/qcloudxr
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

6_Makefile与GCC

第六章 Makefile与GCC 6.1 交叉编译 6.1.1 什么是交叉编译 ​ 简单地说,我们在PC机上编译程序时,这些程序是在PC机上运行。我们想让一个程序在ARM板子上运行,怎么办? ​....S汇编语言源程序预处理、汇编.h预处理文件通常不出现在命令行上 ​ 其他后缀名文件被传递给连接(linker),通常包括: ​ .o:目标文件(Object file,OBJ文件) ​ .a:归档库文件...​ 在写代码时候,其实应该养成一个好习惯就是任何警告错误,我们都不要错过, ​ 编译错误必然是要解决,因为会导致生成目标文件。...6.3 gcc编译2_深入讲解链接过程 ​ 你会发现,可执行文件文件会比源代码大了。这是因为编译最后一步链接会解析代码中外部应用。然后将汇编生成OBJ文件,系统库OBJ文件,库文件链接起来。...为什么clean下命令没有被执行?这是因为Makefile中定义只执行命令目标与工作目录下实际文件出现名字冲突。

3.6K10

手把手教你写一个 Makefile 文件

对于后者,通常是你需要告诉编译头文件所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译就可以编译出中间目标文件。...链接并不管函数所在源文件,只管函数中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以...总结一下,编译链接过程如下: 源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。 在编译时,编译只检测程序语法,和函数、变量是否被声明。...在链接序时链接会在所有的Object File中找寻函数实现,如果找不到,那就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思是说,链接未能找到函数实现...【总结】:通过依赖(prerequisites)中一些文件生成目标(target)文件,目标文件要按照命令(command)中定义规则来生成。 2.

1.6K10
  • Python中断多重循环几种方法,你都知道吗?

    前言: 在编写Python程序时,我们经常会面临需要中断多重循环情况。无论是在搜索特定条件满足数据集合还是在处理嵌套循环时,灵活地中断循环是一项强大技能。...那么,怎么才能跳出多重呢?在此记录备忘一下。 2.跳出多重循环 事实上,Python标准语法是不支持跳出多重循环,所以只能利用一些技巧,大概思路有:写成函数、利用笛卡尔积、利用调试。...这个利用了调试模式中,只要出现报错就退出原理,它伪装了一个错误出来。...协和异步编程: 异步上下文管理: 引入异步上下文管理(async with语法),它使得在异步环境中使用上下文管理更为方便。...深入异常处理: 自定义异常: 自定义异常有助于更好地组织异常层次结构,并为不同错误情况提供更具体异常类型。

    16810

    GCC 编译使用

    里面扩展了所有包含文件、所有定义宏。在编写程序时,有时候查找某个宏定义是非常繁琐事,可以使用`-dM –E’选项来查看。...上面的 main.c 文件中,第 6 行定义变量 i 没有被使用,但是使用“gcc –c –o main.o main.c”进行编译时并没有出现提示。...链接处理归档文件方法是:扫描归档文件,寻找某些成员,这些成员符号目前已被引用,不过还没有被定义。但是,如果链接找到普通 OBJ 文件,而不是库文件,就把这个 OBJ 文件按平常方式链接进来。...+0xf): In function `sub_fun': : undefined reference to `printf' collect2: ld returned 1 exit status 出现了一大堆错误...(9)-u symbol 使链接认为取消了 symbol 符号定义,从而链接库模块以取得定义。可以使用多个 `-u’选项,各自跟上不同符号,使得链接调入附加库模块。

    3.8K31

    实战Makefile前,该知道那些知识?

    make与make clean 生成目标文件规则(make命令): 执行make命令则会根据当前目录Makefile文件定义规则生成对应目标文件。...例如mkdir命令,建立一个目录,如果目录不存 在,则mkdir不会出现错误。如果目录已存在,那么将产生错误。...系统自带变量: 系统自定义了一些变量,通常都是大学,比如CC,PWD,CLFAG等等,有些有默认值,有些没有,比如以下几种,如下 CPPFLAGS:预处理需要选项,如:-l CFLAGS:编译时候使用参数...clean: @rm $(OBJ) output 其中: main.o由main.c生成 add.o 由add.c生成 函数 Makefile提供了大量函数,其中我们经常使用函数主要有两个.../src/main.o 表示:把变量中所有后缀为.c文件替换为.o。命令执行完,OBJ变量值:./src/add.o ./src/main.o

    48320

    Linux环境下通过GDB调试C项目实战

    这个Makefile中几条命令大致为: make clean:清除已经存在result可执行文件 make/make result:将已经得到可执行文件main.o与array.o链接成可执行文件...result,不开启O2优化或采用O0优化,在此之前将main.c和array.c分别编译成可执行文件main.o和array.o make_clean:清除已经存在main.o可执行文件 array_clean...:清除已经存在main.o可执行文件 array:清除已经存在array.o可执行文件并编译array.c生成array.o文件 main:清除已经存在main.o可执行文件并编译mian.c生成...,看起来让人放心,但是,仔细去调试它array.c具体实现代码,就会发现其中函数调用时出现数组越界,这样就会导致缓冲区泄露,可能会修改内存,造成不可知错误,这样是最可怕,因为无法准确预料到,后续会产生难以估计错误...让人放心,但是,仔细去调试它array.c具体实现代码,就会发现其中函数调用时出现数组越界,这样就会导致缓冲区泄露,可能会修改内存,造成不可知错误,这样是最可怕,因为无法准确预料到,后续会产生难以估计错误

    5.3K50

    CC++之makefile写法

    对于后者,通常是你需要告诉编译头文件所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译就可以编译出中间目标文件。...链接并不管函数所在源文件,只管函数中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以...总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译会给出一个警告,但可以生成Object File。...而在链接序时链接会在所有的Object File中找寻函数实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接未能找到函数实现...在找寻的过程中,如果出现错误,比如最后被依赖文件找不到,那么make就会直接退出,并报错,而对于所定义命令错误,或是编译不成功,make根本不理。

    91820

    makefile从入门到放弃——博主吐血整理笔记

    f2.c -o f2.o# -Wall允许发出gcc所有有用报警信息 f1.o:f1.c gcc -c -Wall f1.c -o f1.o#-c表示只编译不链接生成目标文件“.o” main.o...创建和使用变量: 变量类型 预定义变量: 变量名 变量含义 – AR 库文件维护程序名称,默认为ar.AS汇编程序名称,默认值为as。 – CC C编译名称,默认为cc。...通过运行C语言编译来运行链接程序生成(一般是“ld”),其命令是:(CC) (LDFLAGS) n.o x : x.o y.o#并且x.c、y.c都存在时,隐含命令如下 cc -c x.c -o x.o...如果定义了这个变量,那么,make就会在当前目录找不到情况下,到指定目录中去找寻文件了。 VPATH = src:.....makefile内容如下: CFLAGS=-c -Wall -I include test:src1/f1.o src2/f2.o main/main.o gcc src1/f1.o src2/f2.

    1.7K20

    c和fortran混编

    这个机制就是:不论是单一语言模块之间 链接还是不同语言之间混合链接,本质目的都是要链接能找到定义于其他模块中符号,如果全部找到,则链接成功,生成可执行二进制文件。...这正是因为链接链接其实 是ld,gcc调用了它)在foo.o中找到了main.o中需要foo定义,并且在main.o中找到了main定义。...那么,说了这么多其实还是为了明确一点:要让链接找到在一个文件中需要符号定义,那么链接就能成功,就能生成可执行文件了。这也是混编关键! ---- ---- 现在开始真真儿了。...(其实,当fortran不为主程序时,可以不用链接libfrtbegin,起码这个小程序不用) 这里讨论了混编基本原理,就是让链接找到符号所在。从这点出发,一些混编问题都应该有了解决思路。...任何东西,只需要在编译时告诉编译你用了哪个动态链接库就可以了,如下: gcc -o out main.c libf1.so 这时候编译有可能会报告如下错误: libf1.so: undefined

    1.6K41

    makefile终极奥义

    「prerequisites」 生成该target所依赖文件和/或target 「command」 该target要执行命令(任意shell命令) 一个示例 首先还是使用上期「编译链接,你还不会用...OBJ:=main.o #定义变量 #引用变量 ${OBJ} #使用变量 $(OBJ) #推荐使用 除了自己定义变量之外makefile还提供了预定义变量 在隐含规则中命令中,基本上都是使用了一些预先设置变量...CXXFLAGS C++语言编译参数。 CPPFLAGS C预处理参数 LDFLAGS 链接参数。(如:ld ) 隐晦规则 如果我们想定义一系列比较类似的文件,我们很自然地就想起使用通配符。...-f $(OBJ) $(TARGET) 在 rm 命令前面加了一个小减号意思就是,也许某些文件出现问题,但不要管,继续做后面的事....#链接参数 export CFLAGS LDFLAGS TOPDIR := $(shell pwd) export TOPDIR TARGET := app obj-y += main.o

    1.3K30

    错误使用 C++ 模板特化产生

    当编译链接 .o 时候,它会将 .o 中符号全部链接进最终文件中,而当链接 .a 时候,编译则是会看当前链接结果是否存在未定义符号,如果没有,那就不链接这个 .a 文件里面的内容。...在链接 .a 时候,编译发现我已经有 A::print() 了,不需要去链接 .a,因此就跳过了这个库,这就导致了最终输出是编译实例化出来版本,而不是我们定义特化版本。...问题虽然就这样解决了,但是刚刚描述好像有点不对劲。我们说之前错误写法会导致编译自动实例化模板,而链接 .o 文件时候,又会将 .o 中符号链接进最终结果里,那这个时候怎么就没产生符号冲突呢?...如果两个都是强符号,那么就会出现冲突了。 那么,后续正确版本 main.o 符号又是怎样呢?...另外,这顺便也能解释另一件事情:如果 main 依赖于 liba.a,而 liba.a 依赖于 libb.a,那么我们在链接时候就需要先链接 liba.a 再链接 libb.a,否则就会出现符号未定义问题

    34930

    跟我一起写 Makefile(一)

    关于程序编译和链接 —————————— 在此,我想多说关于程序编译一些规范和方法,一般来说,无论是C、C++、还是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件...链接并不管函数所在源文件,只管函数中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以...总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译会给出一个警告,但可以生成Object File。...而在链接序时链接会在所有的Object File中找寻函数实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接未能找到函数实现...在定义好依赖关系后,后续那一行定义了如何生成目标文件操作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作,他只管执行所定义命令。

    28210

    Linux 开发 | 学习 Makefile

    隐式规则 Make 自己推导出来规则,比如目标为 main.o 就推出依赖条件中需要 main.c和对应编译命令 变量定义 类似程序中宏定义, 文本替换。...比如基本例子中最终目标是 edit,而 eidt 依赖 main.o...等文件链接而来,所以 make 就会自动去执行 main.o..等文件生成规则,最后再合成 edit。...cc -o edit main.o command.o ... 第一行说明文件依赖关系,edit 是由 main.o command.o... 这几个文件链接而成,依赖于他们。...执行: $ gcc -MM mian.c 输出: main.o : main.c defs.h 因此,我们借助编译帮我们自动生成依赖关系,并包含到 Makefile 中 -include $(DEPS...sed 替换输出文本,达到目的类似如下 # 编译输出格式 main.o : main.c defs.h # 转换为如下格式 main.o main.d : main.c defs.h 并保存到[.

    5.4K10

    Makefile 使用

    变量导出(export): 在编译程序时,我们会不断地使用“make -C dir”切换到其他目录,执行其他目录里 Makefile。...=定义或使用 define 指令定义变量是延时变量;使用:=定义变量是立即变量。需要注意一点是,?=仅仅在变量还没有定义情况下有效,即?=被用来定义第一次出现延时变量。...开始时这两个文件还没有生成,在执行生成 test 命令之前先将 main.o、sub.o 作为目标查找到合适规则,以生成 main.o、sub.o。...④ 第 7、8 行就是用来生成 main.o、sub.o 规则: 对于 main.o 这个规则就是: main.o:main.c gcc -c -o main.o main.c 对于 sub.o 这个规则就是...⑤ 第 5 行命令在生成 main.o、sub.o 后得以执行。

    4.3K42

    Linux从入门到入土③(GCC、静态与动态链接库、Git、Make、Makefile)

    ]图片GCC编译流程使 用 gcc 进 行 编 译 过 是 一 个 相 对 复 杂 , 可 分 为以下四个阶段:预 处 理 ( Pre-Processing) 编译(Compiling...-fPIC 或 -fpic 参数作用是使得 gcc 生成代码是与位置无关,也就是使用相对位置。-shared参数作用是告诉编译生成一个动态链接库。...动态链接动态链接是一个独立于应用程序进程,属于操作系统,当用户程序需要加载动态库时候动态连接就开始工作了,很显然动态连接根本就不知道用户通过 gcc 编译程序时候通过参数 -L 指定路径...,依次搜索,找到之后结束遍历,最终还是没找到,动态连接就会提示动态库找不到错误信息。...解决方案可执行程序生成之后,根据动态链接搜索路径,我们可以提供三种解决方案,我们只需要将动态库路径放到对应环境变量或者系统配置文件中,同样也可以将动态库拷贝到系统库目录(或者是将动态库链接文件放到这些系统库目录中

    1.5K10

    程序员C语言快速上手——工程篇(十三)

    ,通常会定义clean、install这些伪目标,install一般定义拷贝命令,将生成可执行程序拷贝到应用安装目录下。...定义变量 源文件较多时,可以定义一个变量来保存,后续只需要引用该变量即可,如下,定义src_list来保存源文件列表,引用变量则使用${}包裹....定义变量使用set命令,取消命令可使用unset命令 # 定义变量 src_list set (src_list add.c sub.c mul.c div.c main.c) # 打印日志 message...,继续处理,但会跳过生成 FATAL_ERROR CMake错误,停止处理和生成 内置变量 在cmake中已经内置了一些变量,我们可以直接使用,也可使用set命令去修改 CMAKE_SOURCE_DIR...,因为link_directories命令传入相对路径时,会直接将相对路径传给编译,导致出现找不到问题。

    3K30

    Makefile 使用(在 Linux 中使用 make 命令来编译程序)

    变量导出(export): 在编译程序时,我们会不断地使用“make -C dir”切换到其他目录,执行其他目录里 Makefile。...=定义或使用 define 指令定义变量是延时变量;使用:=定义变量是立即变量。需要注意一点是,?=仅仅在变量还没有定义情况下有效,即?=被用来定义第一次出现延时变量。...开始时这两个文件还没有生成,在执行生成 test 命令之前先将 main.o、sub.o 作为目标查找到合适规则,以生成 main.o、sub.o。...④ 第 7、8 行就是用来生成 main.o、sub.o 规则: 对于 main.o 这个规则就是: main.o:main.c gcc -c -o main.o main.c 对于 sub.o 这个规则就是...⑤ 第 5 行命令在生成 main.o、sub.o 后得以执行。

    8.9K10

    【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程

    连接 链接过程 : 使用 ld 连接, 将 汇编 过程中生成 ".o" 对象文件, 与其它 对象文件 和 库文件连接起来, 生成可执行二进制文件; 连接示例 : 使用 gcc main.o 将汇编过程生成对象文件...中有一个链接将所有的对象文件链接到一起, 生成一个可执行文件; 解析对象文件 : 文件中存放是机器码, 机器码中对其他文件中 函数 或者 变量引用地址没有解析, 当链接程序时候才将这些地址写入...fuck 对象文件链接次序 : 大部分编译都可以随意排列顺序, 但是有的编译需要注意链接次序; -- 编译和连接次序 : 编译链接搜索外部函数 是 从左到右进行查找; -- 文件次序...: 调用函数 对象文件, 该文件应该先于 定义函数 对象文件, 这里 main.o 应该在 kill.o 之前; -- 错误排查 : 如果在编译程序时候, 列出了所有的文件, 但是还出现了 未定义...错误, 就需要注意 文件排列问题; 修改文件流程 : 当修改了一个文件之后, 只需要 重新编译这个文件即可, 之后将这个新编译对象文件 与 原来对象文件进行链接, 即可生成可执行文件; --

    65540

    objdump命令解析

    这不是必须,objdump能自动识别许多格式,比如: objdump -b oasys -m vax -h fu.o 显示fu.o头部摘要信息,明确指出该文件是Vax系统下用Oasys编译生成目标文件....symtab:一个符号表(symbol table),它存放在程序中被定义和引用函数和全局变量信息。一些程序员错误地认为必须通过-g选项来编译一个程序,得到符号表信息。...然而,和编译符号表不同,.symtab符号表不包含局部变量表目。 .rel.text:当链接噐把这个目标文件和其他文件结合时,.text节中许多位置都需要修改。...一般而言,任何调用外部函数或者引用全局变量指令都需要修改。另一方面调用本地函数指令则不需要修改。注意,可执行目标文件中并不需要重定位信息,因此通常省略,除非使用者显式地指示链接包含这些信息。....debug:一个调试符号表,其有些表目是程序中定义局部变量和类型定义,有些表目是程序中定义和引用全局变量,有些是原始C源文件。只有以-g选项调用编译驱动程序时,才会得到这张表。

    4.6K21

    Linux makefile 教程 非常详细,且易懂

    而在链接序时链接会在所有的Object File中找寻函数实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接未能找到函数实现...在找寻的过程中,如果出现错误,比如最后被依赖文件找不到,那么make就会直接退出,并报错,而对于所定义命令错误,或是编译不成功,make根本不理。...如果有文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误。...例如,如果我们执行下面的命令: cc -M main.c 其输出是: main.o : main.c defs.h 于是由编译自动生成依赖关系,这样一来,你就不必再手动书写若干文件依赖关系,而由编译自动生成了...9、Yacc C程序时隐含规则。“.c”依赖文件被自动推导为“n.y”(Yacc生成文件),其生成命令是:“ 10、Lex C程序时隐含规则。

    4.3K20
    领券