0

I've got a CMakeList.txt which builds a static lib:

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);

This compiles ok. I'm then attempting to build a unit test and link with it, and it says the symbol is missing:

Undefined symbols for architecture x86_64:
"splitMIDIValue(unsigned short, MIDIValue*)", referenced from:
  ATMIDIUtilsTests_test_split_midi_value_Test::TestBody() in ATMIDIUtilsTests.cxx.o

nm shows the symbol is external:

0000000000000330 (__TEXT,__text) external _splitMIDIValue

Why are all the symbols missing from my library? ATMIDIUtils.c contains the function implementation but it seems it is not getting compiled into the static lib.

Nick
  • 3,958
  • 4
  • 32
  • 47

1 Answers1

3

Why are all the symbols missing from my library? ATMIDIUtils.c contains the function implementation but it seems it is not getting compiled into the static lib.

They are there and nm(1) is telling you as much. The linker just doesn't find the symbol because you compiled the library with a C compiler, but the unit test is in C++.

You are missing an extern "C" in front of the function prototype. usually the header as a whole is put into an extern "C" block conditional on __cplusplus being defined, like so:

#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_ */

Check this answer for why this is necessary: https://stackoverflow.com/a/11257433/1257035

a3f
  • 8,517
  • 1
  • 41
  • 46
  • Thanks so much that was really confusing me! What would `nm` look like if the symbols weren't present? I thought external meant they weren't present in the lib. – Nick Dec 04 '18 at 14:35
  • @Nick external means they have external linkage (i.e. exported). Not present symbols are undefined. – a3f Dec 04 '18 at 21:07