Compile C++ code to run on ESXi 3.5 - g++

I'm trying to compile a simple c++ program to run inside ESXi 3.5 console window. It seems I'm linking with wrong libraries... Is there a setup described somewhere - which version of G++ and libraries do I have to be using in order to do so?

Here's how I resolved the issue. I did following to compile:
Compiled using gcc under ubuntu
Ran ldd on executable
Copied all libraries that showed up as dependencies to subfolder ESXi-3.5-lib. In my case they were:
ld-linux.so.2
libc.so.6
libgcc_s.so.1
libm.so.6
libstdc++.so.5
Added following switches to gcc:
-nodefaultlibs (to not attempt to link with default libs)
-lc (prevented link error in some crt library)
-fno-stack-protector (prevented another error, some other function was missing)
Following was my final build command:
g++ file1.cpp file2.cpp file3.cpp -o output-biinary-file-name \
ESXi-3.5-lib/ld-linux.so.2 ESXi-3.5-lib/libc.so.6 ESXi-3.5-lib/libgcc_s.so.1\
ESXi-3.5-lib/libm.so.6 ESXi-3.5-lib/libstdc++.so.5 \
-nodefaultlibs -lc -m32 -fno-stack-protector

Related

How can I properly configure the g++ include path with mingw64?

I have installed msys2/mingw64 because I need the g++ compiler. Now, I want to compile some c++ oce which requires openblas. I have installed the package using pacman -S mingw-w64-x86_64-openblas. However, compiling the code fails with
fatal error: cblas.h: No such file or directory
Clearly, the include path does not contain the headers from openblas which are located at C:\msys64\mings64\include\openblas. This is easy to fix by passing -I<include path> as an additional argument to g++.
Now, I was wondering whether there is an automated way to include include files/headers of installed packages in the g++ include path. The same problem also holds for libraries.
For example, pacman might be able to atomatically append these paths onto some environment variable which g++ checks.
The standard way to get compilation and linking options for a library on MSYS2 and other Unix-like systems is to run this command:
pkg-config --cflags --libs openblas
If you're just compiling, use --cflags by itself.
If you're just linking, use --libs by itself.
Here's an example Bash command you could use to compile a single-file program:
g++ foo.cpp $(pkg-config --cflags --libs openblas) -o foo

Why Autotools Ignores Installed Static Library?

I have installed ROHC library (http://rohc-lib.org) using following commands during installation:
autoreconf -if
./configure --enable-static=yes --enable-shared=no --disable-shared --prefix=/usr
make
make install
It successfully installed static (and only static) libraries in /usr/lib directory. It contains librohc.a and librohc.la and no shared-library (i.e. librohc.so*).
I am trying to link this library with OpenVPN. I added following lines in configure.ac of OpenVPN:
AC_CHECK_HEADERS(
[rohc/rohc.h rohc/rohc_comp.h rohc/rohc_decomp.h],
,
[AC_MSG_ERROR([ROHC headers not found])]
)
AC_CHECK_LIB(
[rohc],
[rohc_compress4],
,
[AC_MSG_ERROR([ROHC library not found])]
)
But when I run make in OpenVPN source directory, I get the following error:
/bin/sh ../../libtool --tag=CC --mode=link gcc -DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\" -Wall -Wno-unused-parameter -Wno-unused-function -g -O2 -std=c99 -lrt -o openvpn argv.o base64.o buffer.o clinat.o comp.o compstub.o comp-lz4.o crypto.o crypto_openssl.o crypto_mbedtls.o dhcp.o error.o event.o fdmisc.o forward.o fragment.o gremlin.o helper.o httpdigest.o lladdr.o init.o interval.o list.o lzo.o manage.o mbuf.o misc.o platform.o console.o console_builtin.o console_systemd.o mroute.o mss.o mstats.o mtcp.o mtu.o mudp.o multi.o ntlm.o occ.o pkcs11.o pkcs11_openssl.o pkcs11_mbedtls.o openvpn.o options.o otime.o packet_id.o perf.o pf.o ping.o plugin.o pool.o proto.o proxy.o ps.o push.o reliable.o route.o schedule.o session_id.o shaper.o sig.o socket.o socks.o ssl.o ssl_openssl.o ssl_mbedtls.o ssl_verify.o ssl_verify_openssl.o ssl_verify_mbedtls.o status.o tls_crypt.o tun.o win32.o rohc.o trunk.o cryptoapi.o ../../src/compat/libcompat.la -lnsl -lresolv -llzo2 -llz4 -lssl -lcrypto -ldl -lrohc
libtool: link: gcc -DPLUGIN_LIBDIR=\"/usr/local/lib/openvpn/plugins\" -Wall -Wno-unused-parameter -Wno-unused-function -g -O2 -std=c99 -o openvpn argv.o base64.o buffer.o clinat.o comp.o compstub.o comp-lz4.o crypto.o crypto_openssl.o crypto_mbedtls.o dhcp.o error.o event.o fdmisc.o forward.o fragment.o gremlin.o helper.o httpdigest.o lladdr.o init.o interval.o list.o lzo.o manage.o mbuf.o misc.o platform.o console.o console_builtin.o console_systemd.o mroute.o mss.o mstats.o mtcp.o mtu.o mudp.o multi.o ntlm.o occ.o pkcs11.o pkcs11_openssl.o pkcs11_mbedtls.o openvpn.o options.o otime.o packet_id.o perf.o pf.o ping.o plugin.o pool.o proto.o proxy.o ps.o push.o reliable.o route.o schedule.o session_id.o shaper.o sig.o socket.o socks.o ssl.o ssl_openssl.o ssl_mbedtls.o ssl_verify.o ssl_verify_openssl.o ssl_verify_mbedtls.o status.o tls_crypt.o tun.o win32.o rohc.o trunk.o cryptoapi.o ../../src/compat/.libs/libcompat.a -lrt -lnsl -lresolv -llzo2 -llz4 -lssl -lcrypto -ldl /usr/lib/librohc.so
gcc: /usr/lib/librohc.so: No such file or directory
Yes, /usr/lib/librohc.so does not exist, but /usr/lib/librohc.a exists. Why is it not linking with the static library /usr/lib/librohc.a at absence of .so ?
You may ask me why I am not installing shared libs of ROHC; answer is that I want to force static linking with ROHC, and when it is done I will uninstall ROHC libs.
If someone could show me how to do this static linking without installing ROHC first (like adding dependency to configure.ac or Makefile.am of OpenVPN), it would be better for me.
Note that, both OpenVPN and ROHC library require autotools.
I specified --libdir=/usr/lib64 with ./configure of ROHC library and finally the build system used the static library librohc.a when linking with OpenVPN. I installed ROHC with:
autoreconf -if
./configure --enable-static --disable-shared --prefix=/usr --libdir=/usr/lib64
make
make install
Now it installs the library as /usr/lib64/librohc.a and Compilation of OpenVPN successfully finds and links to it.
And surely, it took place in a 64 bit machine (CentOS 6). In a 32 bit environment (OpenWrt in a 32-bit MIPS router) where there is nothing like /usr/lib64, the problem in the question does not take place.

undefined reference to `shm_open' - how can I pinpoint the culprit?

I am trying to build a simple program against a library, which itself depends on librt. The library compiles just fine and the -lrt flag is used there. The program also builds fine on amd64 using cmake - but on arm64, it fails. This is not cross-compilation, but directly building it on the target. I'm using a normal cmake build system (cmake ..; make).
The exact same build system can also compile a different program, which uses the same library, but not the same functions from it.
Here is the build error:
[100%] Linking C executable mrun-talker
/usr/lib/gcc/aarch64-linux-gnu/7/../../../../lib/libsec-common.so: undefined reference to `shm_open'
/usr/lib/gcc/aarch64-linux-gnu/7/../../../../lib/libsec-common.so: undefined reference to `shm_unlink'
And here is the linker command:
/usr/bin/cc CMakeFiles/sec-talker.dir/main.c.o -o sec-talker -lsec-common -lsec-rosc -lsec-api -ltert -lgcov -lm -lrt -lpthread
The linker command does contain the -lrt flag at the end of the command and the lrt.so is available on the target.
Is there a chance that although the library compiles just fine, it does not properly link and causes this error later when I try to use it?
Full cmake-file:
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId})
set(ExecName ${ProjectId})
enable_language(C)
find_package(Threads)
add_executable(${ExecName} main.c)
target_link_libraries(
${ExecName}
# sec libraries
sec-common
sec-rosc
sec-api
tert
# system libraries
gcov
m
Threads::Threads
rt
)
link_directories("/usr/local/lib")
install(TARGETS ${ExecName})
/edit
I used ldd to check the linking of the libsec-common. Here is the result of the (working) amd64 version:
# ldd /usr/lib/libsec-common.so
linux-vdso.so.1 (0x00007fff7e922000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffa350ef000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffa356ec000)
And of the (not-working) arm64 version.
# ldd /usr/lib/libsec-common.so
linux-vdso.so.1 (0x0000ffffb2dc6000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffb2c26000)
/lib/ld-linux-aarch64.so.1 (0x0000ffffb2d9b000)
I don't see an issue here tbh.
The issue here was that the dependency itself did not correctly link it's dependency.

Error when linking GSL with -static

I have written a programm in c++. Linking and runiing is working, as long as I don't use the "-static" option for g++. But I have to run it from an Antergos USB-Live Stick with default settings and there is no GSL included. In the manual of GSL they recommend
$ g++ -c main.cpp
$ g++ -static main.o -lgsl -lgslcblas -lm -lnlopt
But for this code I receive an error message:
/usr/bin/ld: cannot find -lgsl
/usr/bin/ld: cannot find -lgslcblas
collect2: Fehler: ld gab 1 als End-Status zurück
I tried it as this question, but it didn't work for me. When I run
$ g++ -O2 -o test main.cpp -lgsl -lgslcblas -lnlopt -lm
$ lld test
it prints
linux-vdso.so.1 (0x00007fffa5b95000)
libgsl.so.19 => /usr/lib/libgsl.so.19 (0x00007f8748c9a000)
libgslcblas.so.0 => /usr/lib/libgslcblas.so.0 (0x00007f8748a5d000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f87486d5000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f87483d1000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f87481ba000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f8747e1c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f87490fe000)
So I tried to create a symlink, but I do have also "libgsl.so"
$ ls /usr/lib/libgsl
libgslcblas.so libgslcblas.so.0.0.0 libgsl.so.19
libgslcblas.so.0 libgsl.so libgsl.so.19.3.0
Am I doing something stupid? Thank your for your help.
When you pass -lgsl, by default you request the linker to
find and link either the shared library libgsl.so or the static
library libgsl.a and to prefer the shared library, if both are found
in the same search directory. The linker will search, first, in any
directories you have specified with the -L/path/to/search options,
in the order you specified, and then in its default search directories
(/usr/lib, etc.). Likewise for -lgslcblas.
But when you pass the linkage option -static to gcc/g++, it prevents
linking with any shared libraries. Shared libraries, libgsl.so, libgslcblas.so
will be ignored. Static libraries libgsl.a, libgslblas.a, must be
found, in some or other of the search directories, for the linkage to
succeed.
The linker is saying:
/usr/bin/ld: cannot find -lgsl
/usr/bin/ld: cannot find -lgslcblas
because it can't find those static libraries - presumably because you
haven't installed them.
You do not say what linux distro you are working on, but if the package
that provides libgsl and libgslcblas is called, say, libgsl[suffix]
then there will be a corresponding package called libgsl-dev, libgsl-devel,
or similar. This will be the development version of the package,
for the use of people who want to develop software that links with libgsl
or libgslcblas. The development package will require the libgsl package as a dependency
- so it will install the same stuff - and will in addition contain the
library's header files and the static version of the library.
So you need to install the libgsl development package for your distro.
For Ubuntu, for example, that is libgsl-dev:
Later
I gather that your distro, Arch Linux, does not do separate dev packages. You
need to build the static libraries from source. To do that you will need
at least to have installed:
GNU Make
GNU autotools (autoconf, automake, libtool)
GCC (C compiler)
texinfo
Then to make a default build:
Get the gsl source package from https://savannah.gnu.org/git/?group=gsl
either by cloning the git repo or downloading a current tar.gz tarball
and extracting it.
cd into the package directory.
run ./autogen.sh. This will succeed provided the GNU autotools prerequisites
are fulfilled.
run ./configure --enable-maintainer-mode (as ./autogen.sh will have prompted you).
This will succeed provided that the package dependencies are satisfied
and environment sanity checks pass.
run make
If make completes without errors - which will take a matter of minutes -
then, as root, run make install.
If all is well, this will install your missing static libraries:
/usr/local/lib/libgsl.a
/usr/local/lib/libgslcblas.a
You should not need to modify your linkage command for the linker to find
them: /usr/local/lib is a default linker search path.

Using libdl.so in MinGW

I want to generate a dll file in MinGW, I have several object dependencies in order to do that, one of my object dependencies is libdl.so, I add this object in unix simply as :
g++ xx.o yy.o /usr/lib/libdl.so -o module.so
but in MinGW, I don't have any idea how to add this object. any ideas?
There is a MinGW port of libdl that you can use just like under Unix. Quote from the website:
This library implements a wrapper for dlfcn, as specified in POSIX and SUS, around the dynamic link library functions found in the Windows API.
It requires MinGW to build.
You may get pre-built binaries (with MinGW gcc 3.4.5) and a bundled source code from the Downloads section.
The following commands build and install it in a standard MinGW installation (to be run from your MinGW shell):
./configure --prefix=/ --libdir=/lib --incdir=/include && make && make install
To compile your library as a DLL, use the following command:
g++ -shared xx.o yy.o -ldl -o module.dll
I encountered the same problem (msys2, 32bit version of compiler etc.).
For me I found out that the libdl.a was available in /usr/lib but not in /mingw32/lib. I was able to solve the problem by linking it to the /mingw32/lib folder:
ln -s /usr/lib/libdl.a /mingw32/lib