This question already has an answer here:
linking with libavcodec, still seeing undefined references
(1 answer)
Closed 4 months ago.
I'm on Ubuntu 20.04 trying to compile some code that uses libav. Take the following example script:
// main.c
#include <libavcodec/avcodec.h>
int main()
{
avcodec_find_encoder((enum AVCodecID) 0);
return 0;
}
If I build this with gcc test.c -lavcodec it builds just fine, but if I build it with g++ test.c -lavcodec I get:
/usr/bin/ld: /tmp/ccHxMTp1.o: in function `main':
test.c:(.text+0xe): undefined reference to `avcodec_find_encoder(AVCodecID)'
collect2: error: ld returned 1 exit status
I think you're 'suffering' from C++ name mangling. Try wrapping the #include line with an extern "C" {, } pair...
extern "C" {
#include <libavcodec/avcodec.h>
}
int main()
{
avcodec_find_encoder((enum AVCodecID) 0);
return 0;
}
I am trying to compile a c++ project in Eclipse CDT with third party C project (minimodem https://github.com/kamalmostafa/minimodem), Currently my project simply contains a few cpp files and folder inside the source folder with C files. I have included c headers the main.cpp c files using
extern "C"
{
#include "minimodem/simpleaudio.h"
#include "minimodem/fsk.h"
#include "minimodem/databits.h"
}
the code compiles but breaks at linking with below error
**** Build of configuration Debug for project Sample_Test ****
make all
Building target: Sample_Test
Invoking: GCC C++ Linker
g++ -L/usr/include -o "Sample_Test" ./minimodem/baudot.o ./minimodem/databits_ascii.o ./minimodem/databits_baudot.o ./minimodem/databits_binary.o ./minimodem/databits_callerid.o ./minimodem/databits_uic.o ./minimodem/fsk.o ./minimodem/simple-tone-generator.o ./minimodem/simpleaudio-alsa.o ./minimodem/simpleaudio-benchmark.o ./minimodem/simpleaudio-pulse.o ./minimodem/simpleaudio-sndfile.o ./minimodem/simpleaudio.o ./minimodem/uic_codes.o ./aes256.o ./main.o -lfftw3f -lasound -lpulse-simple -lpulse -lsndfile
./minimodem/simpleaudio.o: In function `simpleaudio_open_stream':
/home/user1/workspace/Sample_Test/Debug/../minimodem/simpleaudio.c:88: undefined reference to `simpleaudio_backend_pulseaudio'
makefile:45: recipe for target 'Sample_Test' failed
/home/user1/workspace/Sample_Test/Debug/../minimodem/simpleaudio.c:99: undefined reference to `simpleaudio_backend_alsa'
/home/user1/workspace/Sample_Test/Debug/../minimodem/simpleaudio.c:105: undefined reference to `simpleaudio_backend_pulseaudio'
collect2: error: ld returned 1 exit status
make: *** [Sample_Test] Error 1
**** Build Finished ****
inside simpleaudio.c the function simpleaudio_open_stream (third party C code)
..
#include "simpleaudio.h"
#include "simpleaudio_internal.h"
..
simpleaudio_open_stream(
...
simpleaudio *sa = calloc(1, sizeof(simpleaudio));
...
#if USE_PULSEAUDIO
sa->backend = &simpleaudio_backend_pulseaudio;
#elif USE_ALSA
..
#if USE_ALSA
case SA_BACKEND_ALSA:
sa->backend = &simpleaudio_backend_alsa;
break;
#endif
#if USE_PULSEAUDIO
case SA_BACKEND_PULSEAUDIO:
sa->backend = &simpleaudio_backend_pulseaudio;
break;
#endif
...
)
the structs linker is unable to find reside in simpleaudio_internal.h
extern const struct simpleaudio_backend simpleaudio_backend_benchmark;
extern const struct simpleaudio_backend simpleaudio_backend_sndfile;
extern const struct simpleaudio_backend simpleaudio_backend_alsa;
extern const struct simpleaudio_backend simpleaudio_backend_pulseaudio;
I am using pre-built LLVM/Clang 3.8.0 binaries on Ubuntu 16.04.2, 64 bit. I tried to lift a minimal program to LLVM IR, then link the IR to DataFlowSanitizer libraries to produce executable code. In the second step, the process throws a bunch of linker errors.
#include <sanitizer/dfsan_interface.h>
#include <assert.h>
int main(void) {
int i = 1;
dfsan_label i_label = dfsan_create_label("i", 0);
dfsan_set_label(i_label, &i, sizeof(i));
return 0;
}
clang -c -emit-llvm -fsanitize=dataflow test2.c -o test2.bc
clang -fsanitize=dataflow test2.bc -o test2
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/Scrt1.o:
In function _start':(.text+0x20): undefined reference tomain'
/tmp/test2-c642ef.o: In function dfs$main':
test2.bc:(.text+0x96): undefined reference todfs$dfsan_create_label'
test2.bc:(.text+0xeb): undefined reference to dfs$dfsan_set_label'
/tmp/test2-c642ef.o: In functiondfs$dfsw$dfsan_create_label':
test2.bc:(.text+0x16e): undefined reference to
dfs$dfsan_create_label'
/tmp/test2-c642ef.o: In functiondfs$dfsw$dfsan_set_label':
test2.bc:(.text+0x1e4): undefined reference to `dfs$dfsan_set_label'
clang-3.8: error: linker command failed with exit code 1 (use -v to
see invocation)
Any idea what might I be doing wrong?
dllwrap is the tool of the GNU GCC in mingw .It be used to build .dll file like gcc or g++.but I found it did not work well with like below:
hello3.cpp
#include<iostream>
extern "C" void MyDllSay( void )
{
}
hello3.def
LIBRARY hello3.dll
EXPORTS
MyDllSay #1
hello = MyDllSay #2
the compiler code is
g++.exe -c -O3 hello3.cpp
dllwrap.exe -o hello3.dll hello3.o --def hello3.def --output-lib
libhello3.a
the error report is
hello3.o:hello3.cpp:(.text+0x8): undefined reference to
std::ios_base::Init::~I nit()'
hello3.o:hello3.cpp:(.text.startup+0xc): undefined reference to
std::ios_base:: Init::Init()' collect2.exe: error: ld returned 1 exit
status
if I set the hello3.cpp like this
//#include<iostream>
#include<fstream>
extern "C" void MyDllSay( void )
{
}
or like this
//#include<iostream>
extern "C" void MyDllSay( void )
{
}
everything is fine.
How to make dllwrap work with iostream?
Thanks a lot in advance for any help !
I just tested the a option in dllwrap .It worked well,I will check it further .
but i can't find the explaintion in dllwrap old wiki
the option is
-lstdc++
the new compiler is
dllwrap.exe -o hello3.dll hello3.o --def hello3.def --output-lib
libhello3.a -lstdc++
This is my first program with winsock. As you can see, I've #include <winsock2.h> and linked ws2_32.dll, but the code still doesn't compile:
#include<winsock2.h>
#pragma comment(lib, "ws2_32")
class CInitSock{
public:
CInitSock(BYTE minorVer=2,BYTE majorVer=2){
//initialize WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer,majorVer);
if(::WSAStartup(sockVersion,&wsaData)!=0){
exit(0);
}
}
//release winSock libary
~CInitSock(){
::WSACleanup();
}
};
#include "CInitSock.h"
#include<stdio.h>
CInitSock initSock;
int main(void){
char szHost[256];
::gethostname(szHost,256);
hostent *phost = ::gethostbyname(szHost);
in_addr addr;
for(int i = 0;;i++){
char *p = phost->h_addr_list[i];
if(p==NULL){
break;
}
memcpy(&addr.S_un.S_addr,p,phost->h_length);
char *szIp = ::inet_ntoa(addr);
printf("%s \n",szIp);
}
}
This is the error:
mingw32-make.exe -f "D:\project\c_program\Makefile.win" all
g++.exe GetAllIPs.o -o win_socket.exe -L"D:/tools/develepment/Dev-Cpp/MinGW64/x86_64- w64-mingw32/lib" -L"D:/tools/develepment/Dev-Cpp/MinGW64/lib32" -static-libgcc -mwindows -g3
GetAllIPs.o: In function `main':
D:\project\c_program/GetAllIPs.cpp:6: undefined reference to `__imp_gethostname'
D:\project\c_program/GetAllIPs.cpp:7: undefined reference to `__imp_gethostbyname'
D:\project\c_program/GetAllIPs.cpp:15: undefined reference to `__imp_inet_ntoa'
GetAllIPs.o: In function `CInitSock::CInitSock(unsigned char, unsigned char)':
D:\project\c_program/CInitSock.h:10: undefined reference to `__imp_WSAStartup'
GetAllIPs.o: In function `CInitSock::~CInitSock()':
D:\project\c_program/CInitSock.h:16: undefined reference to `__imp_WSACleanup'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe: *** [win_socket.exe] Error 1
Now I'm totally confused...
The pragma you use only works for the Visual C++ Compiler and will be ignored by the gcc
#pragma comment(lib, "ws2_32")
you have to add the ws2_32.lib it manually in the makefile.
like:
-L"ws2_32"
(I guess it was without the ".lib" at the end)
at the end of the g++ line. You have of course add the full path which I have not by hand at the moment.
I met the same problem with you. I solved it by adding a command -lwsock32.
you can add the command according follow steps:
tools
compiler options
choose general
click add the following commands when calling the compilers
then you can add the above command -lwsock32.
add
-lwsock32
to your command-line instead of #pragma when compiling with MinGW
g++ src/main.cpp -o release/myApp.exe -lwsock32
In DevC++, navigate to Project >> Project Options (or via usually ctrl+h); then in the "Parameters" tab there is a button "Add Library or Object" and then add libws2_32.a.
For codeblocks under wnidows : go to
Project -> Build Options -> Linker settings (make sure the project is selected on the left, not a build target) and add (type in) in the left list the library "ws2_32"