我有一个CMakeList.txt
可以构建一个静态库:
project(SharedComponents C)
cmake_minimum_required(VERSION 3.12)
set(CMAKE_C_STANDARD 99)
include_directories(../include)
add_library(SharedComponents STATIC ATMIDIUtils.c ../include/ATMIDIUtils.h)
ATMIDIUtils.c
void splitMIDIValue(MIDILongValue value, MIDIValue * _Nonnull separated)
{
separated->MSB = (value >> 7) & ATMIDIMaxValue;
separated->LSB = value & ATMIDIMaxValue;
}
ATMIDIUtils.h
void splitMIDIValue(MIDILongValue value, MIDIValue * _Nonnull separated);
这可以编译。然后,我试图建立一个单元测试并与之链接,它说该符号丢失了:
Undefined symbols for architecture x86_64:
"splitMIDIValue(unsigned short, MIDIValue*)", referenced from:
ATMIDIUtilsTests_test_split_midi_value_Test::TestBody() in ATMIDIUtilsTests.cxx.o
nm显示符号是外部的:
0000000000000330 (__TEXT,__text) external _splitMIDIValue
为什么我的图书馆中所有的符号都不见了? ATMIDIUtils.c
包含函数实现,但似乎没有被编译到静态库中。
答案 0 :(得分:3)
为什么我的图书馆中所有的符号都不见了? ATMIDIUtils.c包含函数实现,但似乎没有将其编译到静态库中。
他们在那里,nm(1)
在告诉你很多。链接器只是找不到符号,因为您使用C编译器编译了库,但是单元测试使用C ++。
您在函数原型之前缺少extern "C"
。通常将标头作为一个整体放在extern "C"
块中,条件是要定义__cplusplus
,如下所示:
#ifndef ATMIDI_UTILS_H_
#define ATMIDI_UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
void splitMIDIValue(MIDILongValue value, MIDIValue * _Nonnull separated);
#ifdef __cplusplus
}
#endif
#endif /* ATMIDI_UTILS_H_ */
请检查以下答案以了解为什么这样做是必要的:https://stackoverflow.com/a/11257433/1257035