Building gcc plugin for windows on linux - c++

Try to build the following gcc plugin on linux for windows with mingw cross compiler. The plugins are from the built avr compiler also for windows. Adapted the following plugin https://github.com/jcmvbkbc/avr-flash-vtbl.
#include <gcc-plugin.h>
#include <cp/cp-tree.h>
#ifdef _WIN32
__declspec(dllexport)
#endif
int plugin_is_GPL_compatible = 1;
void fn(void *gcc_data, void *user_data)
{
TYPE_ADDR_SPACE (TREE_TYPE (vtbl_type_node)) = 1;
TYPE_ADDR_SPACE (TREE_TYPE (vtbl_ptr_type_node)) = 1;
}
#ifdef _WIN32
__declspec(dllexport)
#endif
int plugin_init (struct plugin_name_args *plugin_info,
struct plugin_gcc_version *version)
{
register_callback("", PLUGIN_START_UNIT, fn, NULL);
return 0;
}
Output during compile and linking:
i686-w64-mingw32-g++ -shared -I/home/andreas/omgwtfbbq/win64/bin/../lib/gcc/avr/9.2.0/plugin/include -Wl,--export-all-symbols /home/andreas/
omgwtfbbq/win64/bin/../lib/gcc/avr/9.2.0/plugin/cc1plus.exe.a avr-flash-vtbl.c -o avr-flash-vtbl.so -I./
/usr/bin/i686-w64-mingw32-ld: /tmp/cc28ZVde.o:avr-flash-vtbl.c:(.text+0x4): undefined reference to `cp_global_trees'
/usr/bin/i686-w64-mingw32-ld: /tmp/cc28ZVde.o:avr-flash-vtbl.c:(.text+0x10): undefined reference to `cp_global_trees'
/usr/bin/i686-w64-mingw32-ld: /tmp/cc28ZVde.o:avr-flash-vtbl.c:(.text+0x44): undefined reference to `register_callback'
collect2: error: ld returned 1 exit status
make: *** [Makefile:11: avr-flash-vtbl.so] Fehler 1
The compiler flags are adapted from https://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html. Has anybody already faced such a issue?

Problem is solved. Changed host compiler from i686-w64-mingw32-g++ to x86_64-w64-mingw32-g++ and changed the order of the options. /home/andreas/omgwtfbbq/win64/bin/../lib/gcc/avr/9.2.0/plugin/cc1plus.exe.a must go after avr-flash-vtbl.c.

Related

g++ can't find libavcodec, but gcc can [duplicate]

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

eclipse CDT g++ unable to link minimodem c code in c++ project

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;

Linker error while linking DataFlowSanitizer to LLVM IR

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 could not work with <iostream>?

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++

undefined reference to `__imp_WSACleanup'

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"