I think the functions defined in nouveau/nouveau.h also should in the extern "C" {} block.
Code
I write a test code follow the tests/nouveau/threaded.c.The file is test_libdrm.cpp like this:
#include <fcntl.h>
#include <stdio.h>
#include "xf86drm.h"
#include "nouveau.h"
int main(int argc, char** argv) {
drmVersionPtr version;
int fd;
char* device = NULL;
if (argc < 2) {
fprintf(stderr, "Usage: %s <device>\n", argv[0]);
return 1;
}
device = argv[1];
fd = open(device, O_RDWR);
if (fd < 0) {
fprintf(stderr, "Opening nouveau render node failed with %i\n", fd);
return -fd;
}
version = drmGetVersion(fd);
if (version) {
printf("Version: %d.%d.%d\n", version->version_major, version->version_minor, version->version_patchlevel);
printf(" Name: %s\n", version->name);
printf(" Date: %s\n", version->date);
printf(" Description: %s\n", version->desc);
drmFreeVersion(version);
}
struct nouveau_device *nvdev;
int err;
err = nouveau_device_wrap(fd, 0, &nvdev);
if (err < 0) {
fprintf(stderr, "nouveau_device_wrap err: %d", err);
return 1;
}
return 0;
}
Experiments
I try some experiment, and the results is like this:
1.
script: gcc test_libdrm.cpp -o test_libdrm -ldrm_nouveau -ldrm
error: undefined reference to `nouveau_device_wrap(int, int, nouveau_device**)'
2.
script: gcc -xc++ test_libdrm.cpp -o test_libdrm -ldrm_nouveau -ldrm
error: undefined reference to `nouveau_device_wrap(int, int, nouveau_device**)'
3.
script: gcc -xc test_libdrm.cpp -o test_libdrm -ldrm_nouveau -ldrm
it is correct, i got the test_libdrm file.I analysis the test_libdrm file use readelf.
script: readelf -sW test_libdrm
result:
Symbol table '.dynsym' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND nouveau_device_wrap
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.34 (2)
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND drmFreeVersion
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@GLIBC_2.4 (3)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (4)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fprintf@GLIBC_2.2.5 (4)
8: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND drmGetVersion
10: 0000000000000000 0 FUNC GLOBAL DEFAULT UND open@GLIBC_2.2.5 (4)
11: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
12: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (4)
13: 0000000000004020 8 OBJECT GLOBAL DEFAULT 26 stderr@GLIBC_2.2.5 (4)
4.
script: gcc -xc++ -c test_libdrm.cpp -o test_libdrm.cpp.o -ldrm_nouveau -ldrm
it is correct, i got the test_libdrm.cpp.o file.I analysis the test_libdrm.cpp.o file use readelf.
script: readelf -sW test_libdrm
result:
Symbol table '.symtab' contains 13 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test_libdrm.cpp
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
3: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .rodata
4: 0000000000000000 448 FUNC GLOBAL DEFAULT 1 main
5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND stderr
6: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND fprintf
7: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND open
8: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND drmGetVersion
9: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND printf
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND drmFreeVersion
11: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _Z19nouveau_device_wrapiiPP14nouveau_device
12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __stack_chk_fail
result
I compare above four experiments carefully. I find that, the drmGetVersion funtion is in the extern "C" {} block. the nouveau_device_wrap is not. I also find some matiral. The gcc compile will modify the function name when use as c++. So i think, the functions in the nouveau/nouveau.h file is also need in the extern "C" {} block.