代码之家  ›  专栏  ›  技术社区  ›  Nick

cmake使静态库外部的所有符号

  •  0
  • Nick  · 技术社区  · 6 年前

    我有一个 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 回复  |  直到 6 年前
        1
  •  3
  •   a3f    6 年前

    为什么我的图书室里的符号都不见了?ATMIDIUtils.c包含函数实现,但似乎没有编译到静态库中。

    他们在那里 nm(1) 告诉你同样多。链接器只是找不到符号,因为您用C编译器编译了库,但是单元测试是C++。

    你错过了一个 extern "C" 在功能原型前面。通常将标题作为一个整体放入 外部“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