G++ linking batch PATH - c++

I have 2 different g++ compilers on my computer:
one in the standard directory (C:\MinGW),
and one is a portable distribution.
Now I'm trying to link a c++ project.
The problem is, it is linked against boost libraries
compiled with the portable distribution of g++. The standard
installation directory is ofcourse included in the PATH environment
variable. So when I try to compile my project it will produce linker errors.
I tried to create a batch file which added the portable version's directory at the beginning of the PATH variable. With no luck. Maybe some one can help me out?
#echo off
set PATH=%~dp0..\c++\compiler\bin;%PATH%
REM cd /d "%~dp0"
..\c++\compiler\bin\g++ main.cpp ^
-std=c++0x -static-libgcc -static-libstdc++ ^
-I"../c++/include" ^
-L"../c++/lib" ^
-l"boost_serialization-mgw46-mt-1_52" ^
-l"boost_system-mgw46-mt-1_52" ^
-o output.exe -W -O2
pause
Note: I used "..\c++\compiler\bin\" befor the g++ command because I wanted to be sure it it used the right path, but ofcourse it doesn't work the way I expected.

Solved it by recompiling boost with the installed version of GCC.

Related

Compile C++ on Windows

I'm trying to compile C++ on Windows.
The command needed to compile on Linux is:
g++ -O3 -Wall -shared -std=c++11 -fPIC `python -m pybind11 --includes` EO_functions_bipartite.cpp -o extremal_bi.so
I installed MinGW but when I try to compile I get the following error:
g++.exe: error: python: No such file or directory
g++.exe: error: pybind11: No such file or directory
g++.exe: error: unrecognized command line option '-m'
g++.exe: error: unrecognized command line option '--includes EO_functions_bipartite.cpp'
g++.exe: fatal error: no input files
compilation terminated.
Assuming you have python in your path.
The backtick escape thing that embeds the python -m pybind11 --includes command within the g++ doesn't work on cmd.exe in Windows.
Run the python -m pybind11 --includes command on its own line in the cmd shell. Take the output of that command and substitute in into the g++ command. It should be a bunch of -I include params.
So if the output of the python command is this:
-IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\Include -IC:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\pybind11\include
Expand your g++ command to be this:
g++ -O3 -Wall -shared -std=c++11 -fPIC "-IC:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\Include" -IC:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.7_qbz5n2kfra8p0\LocalCache\local-packages\Python37\site-packages\pybind11\include EO_functions_bipartite.cpp -o extremal_bi.so
Notice the quotes I put around the first include directory because it has a space in its path.
The easiest way to start on native Windows if you have a Linux background is to install MSYS2 shell with MinGW-w64. This will provide an actual bash that allows you to run commands almost exactly the same way as on Linux, including support for backticks like in the case of your issue.
Though I would always recommend using $( ... ) instead of backticks, as this allows nesting.
Note that MinGW-w64 also exists on Windows to allow cross-building for Windows from Linux, but that may be a bit more difficult if you have never done any cross-building before.
Also -shared ... -o extremal_bi.so in your command should be replaced with -shared ... -o extremal_bi.dll -Wl,--out-implib,libextremal_bi.dll.a as .so files don't exist on Windows as Windows uses .dll files for shared libraries and the compiler uses .dll.a files as library objects for them.
Finally on Windows you need to tell the compiler or linker which symbols you will be exporting by either writing a libextremal_bi.def starting with the line EXPORTS followed all the symbols you want to be exported and include -def libextremal_bi.def in the link command, or using __declspec(dllexport)/__declspec(dllimport) when defining those symbols, which may be a bit complexer as it requires some conditional defines to determine if the code is being compiled for Windows and if it's during the actual build process of the shared library (__declspec(dllexport)) or code that uses it (__declspec(dllimport)). There is also another method to export all symbols, but that's a dirty method that may more easily cause symbol conflicts.

Copy and pasting .so file doesn't work with linker

I compiled and built the casablanca c++ rest library in my home directory where my absolute path to the necessary .so file was /home/dev/casablanca/Release/build.release/Binaries/libcpprest.so. What I wanted to do was to simply cp and past that .so file to /usr/lib/.. path to default lib search ../ so that I could easily link it with the following command:
g++ index.cpp -I/home/dev/casablanca/Release/include -lcpprest -std=c++11
which compiled fine, but when I ran ./a.out I got the typical runtime error:
couldn't load shared library: libcpprest.so
even after adding the default path of libcpprest.so to LD_LIBRARY_PATH.
However everything worked just fine if I linked the directory where the binary was originally created at:
// ./a.out runs just fine
g++ index.cpp -I/home/dev/casablanca/Release/include \
-L/home/dev/casablanca/Release/build.release/Binaries -lcpprest -std=c++11
I'm guessing that the reason why I can't simply move the .so object where I want to add it is somehow the compiler keeps references to it somehow. How can I install this binary in a different path?
I did compile casablanca on my linux debian ( https://git01.codeplex.com/casablanca ) with procedure https://casablanca.codeplex.com/wikipage?title=Setup%20and%20Build%20on%20Linux&referringTitle=Documentation
after compilation i get a libcpprest.so with that (objdump) :
SONAME libcpprest.so.2.2
so you might want to copy libcpprest.so.2.2 to /usr/lib/libcpprest.so.2.2
or use ldconfig tool to do so.
looking into Release/build.release/Binaries you will find :
libcpprest.so -> libcpprest.so.2.2
libcpprest.so.2.2
then libcpprest.so is just a link, real library is libcpprest.so.2.2
The section you are referring to is tuned by the rpath switch:
g++ -Wl,-rpath,/path/to/lib ...

why self built g++ compiler fails to compile my code

I wanted to use latest g++ compiler(4.9.1) on suse linux, but suse only supports an older g++ version. So, I took a latest source code from one of the gnu mirror sites and compiled it myself. Everything went fine. But when I tried to compile my test code using the built g++, the compilation fails with error,
"/root/home/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/os_defines.h:39:22: fatal error: features.h: No such file or directory".
I can find a "features.h" in "/root/home/include/c++/4.9.1/parallel", but I feel that it should be there in "/root/home/include/c++/4.9.1/" itself.
I copied "/root/home/include/c++/4.9.1/parallel/features.h" to "/root/home/include/c++/4.9.1/" just to see what happens. Now it complains with error "whcar.h" not found.
Have I missed something.
Here are the steps I followed to build g++.
1. /root/home/gcc_build/objdir# ../gcc-4.9.1/configure --prefix=/root/home/ --disable-multilib
2. /root/home/gcc_build/objdir# make -j16
3. /root/home/gcc_build/objdir# make install
4. /root/home/gcc_build/test# /root/home/bin/g++ --sysroot /root/home -m64 test.cpp
I resolved the issue by removing sysroot option and pointing c++ include and library path to my home directory. One thing I noticed was that the g++ source does not come with libc and c header files, and libc has to be installed seperately. But with sysroot option, g++ was trying to look all the header files in my home directory.
Below is the command I used to successfully compile the code.
/root/home/bin/g++ -I /root/home/include/c++/4.9.1 -L /root/home/lib64 -Wl,--rpath=/root/home/lib64 --std=c++0x -m64 test.cpp
Take a look at the GCC Directory Options. It is important to use the correct "specifier" as well (-isystem, -L, -B, -I etc)

compile <json/json.h> in eclipse using c++

I'm trying to include and compile
#include <json/json.h>
However even though I've installed it and included it on the project settings it wouldn't find the path.
here's what I've so far done:
path to libjson:
/usr/include/jsoncpp-src-0.5.0
options in eclipse gcc c++ compiler:
-Ijson_linux-gcc-4.5.2_libmt -O0 -g3 -Wall -c -fmessage-length=0 -ljson_linux-gcc-4.5.2_libmt
libraries in gcc c++ linker:
-L/usr/include/jsoncpp-src-0.5.0/include/
Anything else I forgot to do to make it work?
try adding -I/usr/include/jsoncpp-src-0.5.0 to compiler options
-L indicates where to find shared libraries (e.g. .so)
-I is the search path for the header files.
If the problem occurs during compilation (json.h not found), then you have indicated the wrong -I
If it occurs during linking (symbol not found), then you have indicated a wrong -L, a wrong -l, or forgot to run ldconfig

Clang linker does not look into LD_LIBRARY_PATH

I am trying to build and link a C++, cmake-based project with clang (3.0). This project links to several libraries that are installed in a custom directory /my/dir/. This directory is included in the LD_LIBRARY_PATH and LIBRARY_PATH environment variables. Project builds and links fine with g++.
The link command generated and executed by cmake looks like the following:
/usr/bin/clang++ -O3 stuff.cpp.o -o stuff -rdynamic -lmylib
ld then complains with the following message:
/usr/bin/ld: cannot find -lmylib
The link command above runs fine whenever I manually add -L/my/dir/. Is there a way to link without specifying the -L flag?
The $LD_LIBRARY_PATH environment variable (and its various alternatives on other UNIX-based platforms) is used at runtime, not link time, to find libraries.
Using -L is the correct approach and cannot be avoided.
Note: A better approach under Linux (you don't specify your platform so I'm guessing) is to correctly configure a file in /etc/ld.so.conf.d/ and avoid using $LD_LIBRARY_PATH altogether.