Unexpected undefined reference

2019-03-04 04:33发布

I'm getting an undefined referenced error, not knowing the reason why.

So I have 2 files which makes a static lib : keyboard_input.c, keyboard_input.h

Here's the content of the .h file:

#ifndef __MOD_KBINPUT__
#define __MOD_KBINPUT__

int kbInit();
int kbWait();

int kbTest();

#endif

And the CMakeLists.txt file looks like this:

FILE(
GLOB_RECURSE
sources
*.c
)
INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include/utils/kbreader")
ADD_LIBRARY(keyboardReader ${sources})

Compiling this lib gives some warnings:

src/utils/kbreader/keyboard_input.c: In function ‘kbInit’:
src/utils/kbreader/keyboard_input.c:13:14: warning: assignment from incompatible pointer type [enabled by default]
src/utils/kbreader/keyboard_input.c: In function ‘kbWait’:
src/utils/kbreader/keyboard_input.c:21:55: warning: passing argument 4 of ‘fread’ from  incompatible pointer type [enabled by default]
/usr/include/stdio.h:708:15: note: expected ‘struct FILE * __restrict__’ but argument is of type ‘struct FILE *’

Now, for my main executable (main.cpp):

#include <keyboard_input.h>
int main()
{
  kbTest();
  return 0;
}

Processed by the following CMakeLists.txt file:

include_directories("${PROJECT_SOURCE_DIR}/include/utils/kbreader")

file(
    GLOB_RECURSE
    srcs
    *.cpp
)

add_executable(
    PEM
    ${srcs}
)
target_link_libraries(PEM keyboardReader)

Ends up getting that error:

CMakeFiles/PEM.dir/main.cpp.o: In function `main':
main.cpp:(.text+0xb): undefined reference to `kbTest()'
collect2: ld returned 1 exit status
make[2]: *** [src/PEM/main2/PEM] Error 1
make[1]: *** [src/PEM/main2/CMakeFiles/PEM.dir/all] Error 2

The libkeyboardReader.a is created, and the kbTest() function doesn't do anything except

{return 0; }

If I set the definition of kbTest() in the header file, it works.

But there's something i don't get, when i type: make keyboardReader here is the output:

[ 73%] Building C object src/utils/kbreader/CMakeFiles/KeyboardReader.dir/keyboard_input.c.o
[Warning explained above]
Linking C static library ../../../lib/libKeyboardReader.a

Is there something wrong? Does the note error message makes my lib omit the keyboard_input.c file?

1条回答
Luminary・发光体
2楼-- · 2019-03-04 05:15

You're mixing C and C++ files. To make that work, you just have to tell the C++ compiler that it's calling a C function, by changing the header file like so:

#ifndef MOD_KBINPUT
#define MOD_KBINPUT
/* note I also fixed the macro so you aren't using a system-reserved name */

#if __cplusplus
/* this is the important part */
extern "C" {
#endif

int kbInit();
int kbWait();

int kbTest();

#if __cplusplus
}
#endif

#endif

Otherwise the C++ compiler assumes the function will be given a C++ internal name (which encodes all the type information in the signature, this is what lets the linker distinguish between overloaded functions) and then the linker doesn't find it.

查看更多
登录 后发表回答