MinGW undefined reference libcurl - c++

So i have written an app in c++ to download mp3s from the web using a list.
It uses libcurl to download them.
I am on linux. Compiling with
g++ main.cpp -lcurl -o word2mp3
works fine.
I need an windows executable, but running
x86_64-w64-mingw32-g++ main.cpp -o wordtest returns the
undefined reference to `__imp_curl_easy_init'
followed by the other curl functions. Adding -lcurl to the command also gives an error saying that curl isn't found.
I've tried and searched everywhere, no luck, I'm a beginner.
Link to my github repo: https://github.com/sharpclone/Word2Mp3

You need to compile libcurl with MinGW, or find a precompiled one. The one you installed to compile your app on Linux was compiled with a Linux compiler, and wouldn't work with MinGW.
MSYS2 repos have a bunch of precompiled libraries for different flavors of MinGW.
I've made a script to automatically download those libraries, since their package manager only works on Windows.
git clone https://github.com/holyblackcat/quasi-msys2
cd quasi-msys2
make install _gcc _curl
env/shell.sh
cd ..
git clone https://github.com/sharpclone/Word2Mp3
cd Word2Mp3/
win-clang++ main.cpp -lcurl -o word2mp3
This doesn't rely on an external MinGW installation, and only requires Clang (and LLD) to be installed (a regular Clang for Linux, unlike GCC you don't need to install a special version of it to cross-compile).
Or, if you prefer your existing compiler, you can stop at make install _curl, then manually specify the path to the installed library, normally -Lquasi-msys2/root/mingw64/lib. You just need to make sure the MSYS2 repo you're using matches your compiler.

To fix the undefined reference warning, you need to link to the required library, so the -lcurl is correct and required.
If the compiler cannot find the library, you need to tell him where to find it, that can be done by passing -L followed by the path to the library (that would be the path to the directory where libcurl.dll.a is in).
The order of the parameters can also be relevant, I think the correct order would be -L <path> -lcurl.

Related

libtorrent-rasterbar7: g++ linker unable to find libtorrent/session.hpp

When compiling the libtorrent tutorial 'hello world' with:
g++ main.cpp -o run -ltorrent-rasterbar -lboost_filesystem-mt -L /usr/lib/
=> fatal error: libtorrent/session.hpp: No such file or directory
Despite having libtorrent-rasterbar7 installed (both libtorrent-rasterbar.so.7 and libtorrent-rasterbar.so.7.0.0 exist in /usr/lib/). Also I'm able to run a simple python script that imports and uses libtorrent without issues.
The g++ command I'm using is identical to the solution for a similar issue with version 6 yet still having the error.
You haven't installed the libtorrent-rasterbar header files. The
package you are missing is the libtorrent-rasterbar development
package. What it is called depends on your distro. (On Debian or Ubuntu
it is libtorrent-rasterbar-dev. On Fedora it is libtorrent-rasterbar-devel).
Whenever you want to write an application that links with a packaged library
you need to install not simply the runtime library but the associated development
package, which provides both the runtime library and its header files.
BTW, there is no need to pass -L /usr/lib to the linker as /usr/lib is one of the default linker search directories.

Automatically collect and output all C++ dependencies

Problem
I need my code to compile on a machine that cannot leverage apt-get to install nonstandard C++ libraries but my C++ program has a single #include for an external library that I must use. That library includes many headers and other libraries, meaning that my makefile has many -l and -I to /usr/include/... and /usr/lib/... pointing to my apt-get installed libraries.
What I want
Rather than manually going through and grabbing all of these libraries so that I can include them in my project directory, I am hoping there is a command or flag for make or g++ that will dump all the libraries and headers into a directory for me.
Progress
This and this have helped because adding the -MMD flag to my g++ compile command will dump out a list of about 100 header file locations. But I would like g++ to go one step further and actually do the work of gathering them all together for me, if that feature exists.

Switching gcc version on remote Linux based HPC (no root rights)

There is a specific program i need to run using c++11 libraries offered by gcc-4.8 and higher. The remote HPC on which i am trying to run the program has gcc-4.6.1. I was able to install the gcc-4.8.2 version on the HPC in a user specified directory, say
/share/user/gccInstall
(gccInstall has the /bin and /lib (etc) folders you get after installation)
I need to switch to this version for compiling my program. I tried using update-alternatives --config gcc, but it does not return anything.
Can anyone help me solve this!
EDIT:
Was able to change the gcc version using the following commands:
setenv PATH /share/user/gccInstall/bin
setenv LD_LIBRARY_PATH /share/user/gccInstall/lib
Now gcc --version returns 4.8.2.
But encountered another error while compiling:
g++: error trying to exec 'as': execvp: No such file or directory
what am i missing?
Many Thanks.
If you have a different version of g++ that you want to use then make sure you're getting the right one according to your $PATH or else specify the full path to the g++ you want. The other thing to be aware of is that you will probably need to update the $LD_LIBRARY_PATH environment variable to get the necessary libraries from your new gcc installation.
What exactly is the problem you're having? Can you compile but not run? Does compilation fail? Do you have any error messages you can share?
Assuming as you say that your new GCC installation is
under /share/user/gccInstall then if you add the option
-B/share/user/gccInstall
to each invocation of g++ or gcc then it will have this
effect:
-Bprefix
This option specifies where to find the executables, libraries, include files, and data files of the compiler itself.
(from Options for Directory Search)
This should help, and will perhaps be enough.

How can I compile ndpiReader.c that comes with nDPI library in Windows?

I want to create a .exe of ndpiReader.c demo program that comes with nDPI library. I was successful to compile it on Ubuntu using commands specified on their github page as bellow:
./autogen.sh
./configure
make
I have tried to cross compile it using GCC inside Ubuntu but I wasn't successful. I also tried to use the pcapExample.sln to compile it in Visual Studio 2012, but I keep getting error messages like:
Error 29 error C1083: Cannot open include file: 'ndpi_api.h': No such file or directory
Although ndpi_api.h and all other files that I get this error for already are listed in the project solution explorer.
Has anyone actually been able to make a win32 executable out of this ndpiReader.c file? If yes, please specify the steps, requirements, or a link.
nDPI lib is hosted here: https://github.com/ntop/nDPI
ndpiReader.c is hosted here: https://github.com/ntop/nDPI/tree/dev/example
pcapExample.sln is hosted here: https://github.com/ntop/nDPI/tree/dev/example/Win32
I saw from your other questions that you had already tried to compile this with CYGWIN and ran into a number of problems.
Here’s a step-by-step guide I just used to compile nDPI (including the ndpiReader.exe example):
Install CYGWIN:
Accept the default directories, and pick a mirror.
At the Select Packages step, expand the Devel category, and select the following developer packages to install:
autoconf
autoconf2.5
automake
automake1.15
binutils
cmake
cygwin-devel
gcc-core
gcc-tools-epoch2-autoconf
gcc-tools-epoch2-automake
libtool
make
pkg-config
w32api-headers
w32api-runtime
Install libpcap under CYGWIN:
Download and unpack the Winpcap Developer's pack.
Copy libpacket.a and libwpcap.a from WpdPack\Lib\ to cygwin\lib\
In cygwin\lib, copy libwpcap.a to libpcap.a
In cygwin\usr\include, create a pcap directory
Copy all headers from WpdPack\Include to cygwin\usr\include\pcap
I'm sure you've installed winpcap already as part of everything else you've tried, but double-check that the necessary (packet.dll and wpcap.dll) libraries are already in cygwin\c\WINDOWS\system32.
Now you've got all the necessary tools and libraries to compile nDPI on Windows!
Building nDPI
Download and unpack nDPI again in a clean directory, so you don't get tripped up by any issues from the previous build you tried.
Open a CYGWIN terminal, and cd into the nDPI directory.
Run autogen.sh
./autogen.sh
This should complete without any errors.
If it stops with "somepackage is missing: please install it and try again," you've missed installing a CYGWIN package that is needed to build the source.
If it stops with "Missing libpcap(-dev) library," double-check the previous steps you did to copy libpcap.a in cygwin\lib.
autogen.sh should start running the configure stage for you. (If it doesn't, or part of this stage fails, you can rerun configure after fixing any issue.)
./configure
After checking for a number of things, configure will end by creating a Makefile.
Build the nDPI library, by running make.
make
It will build the library, then try to build the examples, but fail because it can't find pcap.h
cd into the example directory, and manually compile ndpiReader.c by adding -I/usr/include/pcap to the command:
cd example/
gcc -DHAVE_CONFIG_H -I. -I.. -I../src/include -I/usr/include/pcap -g -O2 -c -o ndpiReader.o ndpiReader.c
I included my command as an example. If your compiler command is slightly different, just add -I/usr/include/pcap to what your Makefile had invoked.
Leave the example directory, and resume the make.
cd ..
make
This last step will link ndpiReader with the ndpi library, and create the executable you're looking for.

Boost Python (Suse and Ubuntu)

I created a simple .so library containing definition of a C++ class which should be accessed from Python and used for this purpose boost python library.
When I'm testing this library using x64 Ubuntu it is enough to set LD_LIBRARY_PATH with the path to boost libs before running python. It doesn't work, however, when I'm using x64 Suse.
Altough I'm setting LD_LIBRARY_PATH it seems that Python ignores it.
Is there any specific way to set environmental variables under Suse?
You should never set LD_LIBRARY_PATH, see here and here.
First of all I have to assume that you installed the Boost libraries in a nonstandard location, otherwise the loader would find them automatically. If you have root access to the machine, install the libraries in a standard place (e.g. with the package manager, or in /usr/local/lib).
If you don't have root privileges, set the runpath instead. When using the gcc linker, do this by passing an -rpath option. The gcc compiler can pass options to the linker via -Wl. So call the compiler as follows:
g++ -Wall -Wextra -Wl,-rpath /path/to/boost -L /path/to/boost -lboost_python ...