How to link wsock32 library through g++? - c++

I'm using minGW on windows, trying to compile a c++ program. I've used sockets in there, so I'm trying to link (not include... I've already included winsock.h) the wsock32 library. I know that the -L switch is for linking but none of the following commands work:
g++ C:\program.cpp -Lwsock32.lib
g++ C:\program.cpp -LC:\windows\system32\wsock32.dll
g++ C:\program.cpp -lC:\windows\system32\wsock32.dll
g++ C:\program.cpp -LC:\windows\system32\wsock32.lib
what should I do??

The -L option is for setting the directory where the linker should look for libraries/dlls.
The -l option is for naming the libraries/dlls you want to link with.
That would mean
g++ C:\Program.cpp -LC:\Windows\System32 -lwsock32
should be the command to compile your program from your regular windows command prompt.
I suspect your compiler may look in system32 automatically, so you may want to just try to skip the -L option.

As #Joshua commented, you probably want ws2_32.dll.
The GNU Compiler Collection uses ranlib archives (A files) rather than Visual Studio LIB files.
The w32headers project provides gcc- and g++-compatible headers and archives for most standard Windows DLLs, including ws2_32.dll. The name of the archive is usually the name of the DLL minus the .dll extension, prefixed with lib and suffixed with .a (following the *nix archive naming convention). Thus, the symbols for ws2_32.dll are in libws2_32.a, which can be linked with using ‑lws2_32.
By default, the w32headers archives are in the GNU ld library path, so to be able to link with standard Windows DLLs, there is no need to add library directories with an ‑L option. In your case, the only option that you need is ‑lws2_32:
g++ C:\Program.cpp -lws2_32
Assuming that compilation and linking succeed, the output will be a.exe in the current directory. You can override the name of the output binary with the ‑o option.
NOTE: I used non-breaking hyphens in my answer. If you copy & paste the command line options, be sure to replace all hyphen-looking characters with regular hyphens.

Related

g++ only looks for .lib files

I am using Windows 10 with mingw-w64. I tried compiling a program with a statically linked library. I used this command: g++ main.cpp -Llibs/ -lfoo. But MinGW says it can't find the library files, so I tried renaming foo.a to foo.lib and voila, the compiler found foo.lib. Why doesn't MinGW see *.a files anymore?
The problem is that mingw will not look for <libname>.a files because it does not expect them to exist.
From the docs:
MinGW supports libraries named according to the ".lib" and ".dll" conventions, in addition to the normal "lib.a" convention common on *nix systems
This is because windows does not use the lib prefix for its libraries in the same way that *nix does (on windows a shared library foo would be foo.dll and on *nix it would be libfoo.so). I am not sure how you managed to get a .a missing the lib prefix (unless you renamed it) but your .a files should have a lib prefix in them (when specifying this you omit the lib part so libfoo.a becomes -lfoo)
From the documentation:
when ld is called with the argument ‘-lxxx’ it will attempt to find, in the first directory of its search path,
libxxx.dll.a
xxx.dll.a
libxxx.a
xxx.lib
libxxx.lib
cygxxx.dll
libxxx.dll
xxx.dll
Alternatively, you can pass libs/foo.a directly as an argument to g++.

Linux executable can't find shared library in same folder

I am relatively new to Linux development, having been using Windows for a while now. Anyway, I am compiling a C++ game using g++ on both Windows and Linux (using mingw32 when needed), and am linking against SDL2 and SDL2_mixer. On Windows, one would only need to put the DLL files in the same folder as the executable and everything would run fine. On Linux however, although the code compiled just fine with not even a single warning, I get this at runtime :
./nKaruga: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory
although said shared lib is in the same folder. I looked up several similar cases on Stack Overflow, all of them involving the use of LD_LIBRARY_PATH, and tried it but to no avail.
% LD_LIBRARY_PATH=pwd
% export LD_LIBRARY_PATH
% ./nKaruga
./nKaruga: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory
I want to distribute this program on systems that do not necessarily have admin rights to install dependencies, hence why I am putting the SO in the same folder as the executable.
Thanks by advance !
LD_LIBRARY_PATH is a quick ad-hoc hack to specify alternate library loading search paths. A more permanent and cleaner solution is to specify the specific sets of paths in which libraries shall be searched specific for your particular binary. This is called the rpath (Wikipedia article on it: https://en.wikipedia.org/wiki/Rpath). There are a number of "variables" that can be specified in the binary rpath that get substituted. In your case the rpath variable ${ORIGIN} would be the most interesting for you. ${ORIGIN} tells the dynamic linker to look for libraries within the very same directory in which also the binary resides.
The rpath can be set at link time with the -rpath linker option, i.e. when invoked through GCC the option would be -Wl,-rpath='${ORIGIN}', i.e.
gcc -o program_binary -Wl,-rpath='${ORIGIN}' -lSDL2_mixer a.o b.o …
For an existing binary the rpath can be set post-hoc using the chrpath or patchelf tools; it's better to set it at link time proper, though.

C++ linking boost library

First I built the Boost libraries that require building by going to /usr/local/boost_1_49_0/ and running the bootstrap.sh. This went off alright.
Step (1) created all the .so and .a files in /usr/local/boost_1_49_0/stage/lib
I tested linking against a library, say lboost_regex and #include <boost/regex> in my source code. This also went off alright.
Finally trying out the example on asio, I tried:
g++ -I/usr/local/boost_1_49_0 MAIN.cpp -o MAIN -L/usr/local/boost_1_49_0/stage/lib -lboost_thread -lboost_system -lpthread
(4) compiled alright. But when I run the program with ./MAIN, I get the following error:
./MAIN: error while loading shared libraries: libboost_system.so.1.49.0: cannot open shared object file: No such file or directory
The -L option only sets a compile-time library search path; if you want a shared library to be found at runtime then its directory must be known at runtime.
One way to set this with g++ is to pass -rpath to the linker, via the compiler; in your case you could say -Wl,-rpath -Wl,/usr/local/boost_1_49_0/stage/lib. (This embeds the directory in the executable.)
Another way is to install the libraries in a place that the linker searches by default (e.g. /usr/local/lib might be such a place, depending on how the system is configured).
Yet another way is to set an environment variable such as LD_LIBRARY_PATH (Linux or Solaris) or DYLD_LIBRARY_PATH (Mac OS X), to tell the linker where to search when launching executables from the shell where the variable is set.
Are you sure the shared library is in a place where the loader can find it? Either put it in a system wide directory or the same directory as the executable.
Here's a link with more information about the loader.

How do I add sqlite3 to my project

How do I statically link the sqlite3 libary to my C++ program?
I am using the G++ compiler.
in Unix/Linux you'll have to make sure the library (e.g. libsqlite3.a) is in your LD_LIBRARY_PATH and then you add "-lsqlite3 -static" to the g++ option.
Assuming you're on Linux and using the GNU ld linker:
g++ <your-code> -Wl,--Bstatic -lsqlite3
Of course, if libsqlite3.a isn't in your library path, you have to pass the directory it's in to the compiler as an additional -L flag.
If you don't have a static version (I don't on my system), you either have to check if you can get one or if you'll have to build your own.
On a Linux system I recommend using pkg-config.
Running pkg-config --cflags --libs --static sqlite3 should give you the compiler and linker flags you need.
Go to www.sqlite.org and download the latest version's amalgamation tarball. Include their source files to your project (make file, whatever) and forget about it. It's embedded anyway, they compile in a jiffy, if you put into your version control repo, you know what version you're using in what version of your application and you can forget about linking options. Just remember that their source files are C and not C++.

gcc -l option and .la library files

Could you please explain, how linking with -l option against .la files works?
As far as my experience reaches - i have only linked against static library (.a) files.
Now i took a look at some Qt generated Makefiles and cant figure out, how linker figures out to use/open libQtCore.la file, when -l QtCore switch is specified, instead of looking for libQtCore.a.
Also - gcc manual states, that -l[library name] switch will include lib[library name].a, not lib[libraryname].la.
.la files are as far as I know libtool junk and shouldn't be linked to manually. They are used internally by libtool for whatever reason it needs them. You should link to the *.a file. In a Qt install/build there should be *.a files to link to.