cmake使静态lib中的所有符号都外部

时间:2018-12-04 05:40:49

标签: c cmake

我有一个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包含函数实现,但似乎没有被编译到静态库中。

1 个答案:

答案 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