使文件重复符号
Makefile duplicate symbol
我想花一点时间,我知道SO到处都是这些问题,我已经看了很多:
- Xcode C++::体系结构x86_64的重复符号
- Xcode下体系结构x86_64的重复符号
- ld:1个用于体系结构x86_64的重复符号
我目前正在使用C++为一个学校项目构建反汇编程序,当我运行make文件时,我会遇到重复的符号错误。我担心我的问题比上面列举的例子要复杂一些。我为重复的问题道歉,但经过数小时的搜索和尝试解决问题后,我无法解决问题,我感谢任何人提供的建设性、完整和积极的反馈。
g++
版本3.4.6(是的,我知道,它是旧的学校服务器)make
版本3.81
这是我的生成文件:
CC=g++
CFLAGS=-Wall -O0 -c
all: dasm
dasm: main.o optab.o record_tokenizer.o regex.o
$(CC) -o $@ $^
clean:
rm *.o dasm
看起来Make能够将所有文件转换为各自的对象文件,但链接到单个可执行文件是失败的:
c++ -c -o main.o main.cpp
c++ -c -o optab.o optab.cpp
c++ -c -o record_tokenizer.o record_tokenizer.cpp
c++ -c -o regex.o regex.cpp
g++ -o dasm main.o optab.o record_tokenizer.o regex.o
duplicate symbol _optab in:
main.o
optab.o
duplicate symbol _optab in:
main.o
record_tokenizer.o
duplicate symbol _HEADER_RECORD_REGEX in:
main.o
record_tokenizer.o
duplicate symbol _END_RECORD_REGEX in:
main.o
record_tokenizer.o
duplicate symbol _TEXT_RECORD_REGEX in:
main.o
record_tokenizer.o
duplicate symbol _MOD_RECORD_REGEX in:
main.o
record_tokenizer.o
ld: 6 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [dasm] Error 1
我绝对不是C++专家,也不是Makefile大师,所以我们非常感谢您的帮助。以下是相关文件:
optab.h
#ifndef __dasm__optab__
#define __dasm__optab__
#include <map>
#include <string>
std::map<short, const char*> optab;
void init_optab();
const char* get_instruction(int n);
#endif
正则表达式.h
#ifndef __dasm__regex__
#define __dasm__regex__
#include <regex.h>
bool match(const char* pattern, const char* string);
#endif
record_tokenizer.h
#ifndef __dasm__record_tokenizer__
#define __dasm__record_tokenizer__
#include <vector>
#include <cstdlib>
#include <sstream>
#include "regex.h"
#include "optab.h"
const char* HEADER_RECORD_REGEX = "^H[a-zA-Z|[:space:]]{6}[:digit:]{12}";
const char* END_RECORD_REGEX = "^E([:digit:]{6})?";
const char* TEXT_RECORD_REGEX = "^T[:digit:]{6}[0-1][0-E][:digit:]{,60}"; // TODO: improve on this
const char* MOD_RECORD_REGEX = "^M[:digit:]{8}";
struct Record {
char record_type;
std::string name;
std::string address;
std::vector<std::string> addresses; // used for T records only
};
bool is_valid_record(const char* record, const char* pattern);
const int to_i(std::string n);
const Record tokenize_record(std::string record);
#endif
main.cpp
#include <iostream>
#include "record_tokenizer.h"
using namespace std;
int main(int args, const char* argv[]) {
if(args > 2) {
std::cerr << "Usage: dasm sample.obj" << std::endl;
exit(EXIT_FAILURE);
}
tokenize_record("T0000001E^050000^032003^3F^69101791^1BA0131BC0002F200A3B2FF40F102F014F0000");
return 0;
}
optab.h
中的这一行有问题:
std::map<short, const char*> optab;
包含该.h文件的每个.cpp
文件都将optab
定义为全局变量。这将导致符号被定义多次。
同样的错误将从线路中产生:
const char* HEADER_RECORD_REGEX = "^H[a-zA-Z|[:space:]]{6}[:digit:]{12}";
const char* END_RECORD_REGEX = "^E([:digit:]{6})?";
const char* TEXT_RECORD_REGEX = "^T[:digit:]{6}[0-1][0-E][:digit:]{,60}";
const char* MOD_RECORD_REGEX = "^M[:digit:]{8}";
在CCD_ 6中。
您可以通过以下方式修复它们:
通过使它们成为
extern
变量并仅在一个.cpp
文件中定义它们。通过使它们成为
static
变量。通过使它们成为CCD_ 10。这将适用于字符串,但不适用于
optab
。我想你需要改变它的价值。const char* const HEADER_RECORD_REGEX = ...; const char* const END_RECORD_REGEX = ...; const char* const TEXT_RECORD_REGEX = ...; const char* const MOD_RECORD_REGEX = ...;
这是谷歌搜索";重复符号cerr";,所以我认为在这里回应会有所帮助。
默认情况下,新的gcc/clang(v10,v11)版本对重复符号更加严格,但这种行为可以通过-fcommon
标志进行调整
clang main.c -fcommon
相关文章:
- 使用gcc从静态链接的文件中查找可选符号
- 检测 COFF 对象文件中C++内联符号
- 使用 fopen 打开 .pak 文件并使该文件应用于 const 无符号字符* (C++)
- 如何从二进制文件中的给定符号中获取调用程序图
- 如何将 UTF-8 文本从文件转换为某个可以迭代的容器,并检查每个符号是否为C++字母数字?
- CMake 生成的 MSVC 项目找不到符号,即使为其相关 dll 正确生成了 lib 文件也是如此
- 错误:当我从"WinDbg"打开可执行文件时,找不到符号文件。默认导出 ntdll 的符号.dll
- 可以在 cpp 文件中C++定义为特殊符号的变量β
- 尝试将字符串从文件读取到无符号字符向量中
- C++和带有国家符号的文件路径(也许用 UTF8 编码)
- 体系结构x86_64的未定义符号:c++/ h 文件和 cpp 文件
- 错误LNK2019:未解析的外部符号.c文件到cpp
- Visual Studio 2012 性能分析无法加载符号文件
- 查看给定VC++ exe中的所有符号/文件的方法
- gdb:在0x2aaaaaaab000添加的符号文件系统提供的 DSO 中找不到可加载的部分
- gdb:在添加的符号文件系统提供的编号为0x#的DSO中找不到可加载的节
- 类型是否在最终二进制文件中公开?它们在符号文件和RTTI中可用吗?
- Oracle是否为OCCI/OCI提供公共符号文件(PDB)
- gdb:什么是用于调试的符号文件
- 非常困如何找到符号文件