Meson can't find static libs - meson-build

I can compile my project by running
g++ main.cpp -l:libpj-x86_64-unknown-linux-gnu.a -lpthread -lm -luuid
or
g++ main.cpp /usr/local/lib/libpj-x86_64-unknown-linux-gnu.a -lpthread -lm -luuid
But when I try adding library with either one of:
meson.get_compiler('cpp').find_library('libpj-x86_64-unknown-linux-gnu.a')
meson.get_compiler('cpp').find_library('/usr/local/lib/libpj-x86_64-unknown-linux-gnu.a')
I'm getting error:
ERROR: C++ library 'libpj-x86_64-unknown-linux-gnu' not found

Solution was to add 'dirs' variable even tho file is in standard /usr/local/lib path and to remove .a extension.
cc.find_library('libpj-x86_64-unknown-linux-gnu', dirs: '/usr/local/lib/')
Later of course lib was available inside meson and was added to executable and tested.

Related

Categories in static lib not regocnized at runtime

I am building an executable ("tool") on Linux. Using include $(GNUSTEP_MAKEFILES)/tool.make.
It's linked to a static lib that has also be build with GNUstep. The lib
contains Categories.
The executable builds fine but has errors at runtime not recognizing
methods defined in the static lib's Category:
Uncaught exception NSInvalidArgumentException, reason:
ClassNameOfClassTheCategoryExtends(instance) does not recognize
nameOfMethodInCategory
I am trying to fix that by passing -ObjC to the linker flags (also
tried -all_load) in the executable's GNUmakefile:
ADDITIONAL_LDFLAGS = -ObjC -all_load
But that seems to be ignored by clang. Here is the relevant output of
make install messages=yes debug=yes
clang: warning: argument unused during compilation: '-ObjC'
[-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-all_load'
[-Wunused-command-line-argument]
It looks like ADDITIONAL_LDFLAGS are used compiling, not linking.
Using this leads to the same result:
LDFLAGS := $(LDFLAGS) -ObjC
The excecutables GNUmakefileincludes the following:
include $(GNUSTEP_MAKEFILES)/common.make
# My make
include $(GNUSTEP_MAKEFILES)/tool.make
The resulting command line output is:
$ make install messages=yes debug=yes
This is gnustep-make 2.9.0. Type 'gmake print-gnustep-make-help' for help.
Running in gnustep-make version 2 strict mode.
Making all for tool NameOfExcecutable...
clang -ObjC -fuse-ld=/usr/bin/ld.gold -pthread -fexceptions -rdynamic -fobjc-runtime=gnustep-2.0 -fblocks -o obj/NameOfExcecutable \
./obj/NameOfExcecutable.obj/main.m.o ./obj/NameOfExcecutable.obj/MyClass.m.o ./obj/NameOfExcecutable.obj/StreamRunLoop.m.o ./obj/NameOfExcecutable.obj/Connector.m.o ./obj/NameOfExcecutable.obj/HTTPClient.m.o \
-L/home/user/GNUstep/Library/Libraries -L/usr/GNUstep/Local/Library/Libraries -L/usr/GNUstep/System/Library/Libraries -lgnustep-base -ldispatch -l/path/to/libOwnLib1.a -l/path/to/libOwnLib2.a -l/path/to/libOwnHavingTheCategories.a -l/path/to/libOwnLib4.a -l/path/to/libOwnLib5.a -luuid -lz -lpthread -ldl -lpthread -lobjc -lm
clang: warning: argument unused during compilation: '-ObjC' [-Wunused-command-line-argument]
Question:
What am I doing wrong
or
How can I work around the issue?
After digging into the issue of the linker not knowing the -ObjC flag (which we are used to use in Xcode) it looks like:
only ld.ld64 is aware of this flag
ld.ld64 is a (too genericly named) "linker for macOS" (from LLDB.org)
thus is not available for Linux linkers
To workaround we first stopped using GNUstep makefiles to
disable all GNUstep magic understand what is going on and wrote our own makefiles.
The actual fix to force link/load all .o files was to explicitly pass --whole-archive to the linker:
-Wl,-whole-archive path/to/static/lib/containing/categories/libOwnLib1.a -Wl,-no-whole-archive

linker error using static linking in g++

I am using other people's makefile and get troubles when trying to compile a 'static' version of the exe
I have printed out the makefile's rules and the error is like this:
g++ Main.or System.or Options.or -Wall -lz --static -o main
/usr/bin/ld: cannot find -lz
/usr/bin/ld: cannot find -lstdc++
/usr/bin/ld: cannot find -lm
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
If I do not include the '--static' option in the above command, it works fine.
The makefile also have rules to generate the static lib:
ar -rcsv lib_release.a Main.or System.or Options.or
r - Main.or
r - System.or
r - Options.or
Making Soft Link: lib_release.a -> lib.a
ln -sf lib_release.a lib.a
The -static linkage option instructs the linker to ignore all shared
libaries (libname.so) that could resolve the -lname linkage options (both explicit
and default) and accept only static libraries (libname.a). You have shared libraries installed on
your system that satisfy -lz, -lstdc++, -lm and -lc but no static ones.
For your linkage to work as it stands you must install the static libraries:
libz.a (Compression library)
libstdc++.a (The standard C++ library)
libm.a (The math library)
libc.a The standard C library
by the method that is appropriate to your distro.

How to link in -lpthread -lm -ldl in CMake

I am trying to use cmake to link intel mkl for my code. From mkl link advisor, I should link the library by:
-L${MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_core -lmkl_sequential -lpthread -lm -ldl
I then write a module to find mkl_intel_lp64, mkl_core, and mkl_sequential in Findmkl.cmake:
find_library(lp64_libraries NAMES mkl_intel_lp64 PATHS "${mkl_path}/lib/intel64")
find_library(core_libraries NAMES mkl_core PATHS "${mkl_path}/lib/intel64")
find_library(sequential_libraries NAMES mkl_sequential PATHS "${mkl_path}/lib/intel64")
Then I can link these libraries. While I do not know how to link -lpthread -lm -ldl, I am not sure what this link mean, I can not find any libpthread.a in $MKLROOT/lib/intel64.
Those libraries should exist on each Unix system.
So you can just add:
target_link_libraries(target_name m dl pthread)

Cross-platform static-linking SDL2

I'm building an SDL2/C++ program that needs to be portable to Windows, Mac, and Linux machines which may not have SDL installed.
I've read that static linking is the solution, but I'm not very good with compiling and don't know how to static link.
My program relies only on SDL2, GLU, and OpenGL. I'm compiling C++ with either MinGW (on Windows 8.1) or gcc (on Ubuntu 14.04) -- both of these OS's have SDL installed natively.
Here is my current makefile, derived from a sample makefile given to me by a professor of mine:
# Executable/file name
EXE=experiment
# MinGW
ifeq "$(OS)" "Windows_NT"
CFLG=-O3 -Wall -DUSEGLEW
LIBS= -lSDL2 -lglu32 -lopengl32
CLEAN=del *.exe *.o *.a
else
# OSX
ifeq "$(shell uname)" "Darwin"
CFLG=-O3 -Wall -Wno-deprecated-declarations
LIBS=-framework SDL2 -framework OpenGL
# Linux\Unix\Solaris
else
CFLG=-O3 -Wall
LIBS= `sdl2-config --cflags --libs` -lGLU -lGL -lm
endif
# OSX\Linux\Unix\Solaris
CLEAN=rm -f $(EXE) *.o *.a
endif
# Dependencies
$(EXE).o: $(EXE).cpp FORCE
.c.o:
gcc -c -o $# $(CFLG) $<
.cpp.o:
g++ -std=c++11 -c -o $# $(CFLG) $<
# Link
$(EXE):$(EXE).o
g++ -std=c++11 -O3 -o $# $^ $(LIBS)
# Clean
clean:
$(CLEAN)
# Force
FORCE:
To link with static library you either specify path to library file
gcc -o out_bin your_object_files.o path/to/lib.a -lfoo
or ask linker to use static version with -Bstatic linker flag. Usually you'll want to reset linking back to dynamic for the rest of the libraries, e.g. for static SDL2 and GLU but dynamic GL:
gcc -o out_bin your_object_files -Wl,-Bstatic -lSDL2 -lGLU -Wl,-Bdynamic -lGL
That of course implies that static versions of libraries are present in library search path list (.a libs for gcc on all specified platforms, although MSVC uses .lib for static libraries).
However you usually don't really want to do that at all. It is common practice for software to either depend on some libs (widespread on linux, with packages and dependendices lists) or bring required libraries with it. You can just distribute SDL dynamic library with your program and load it with LD_LIBRARY_PATH or relative rpath.
Please also note that newer SDL2 implements dynamic loading of functions which provides a way to override SDL with user-specified dynamic library, even if linked statically.
It wasn't related directly to static linking. When static linking, I had to include all of SDL's dependency libraries. Turns out, having -mwindows causes console communication to fail.

cmake how to link static library not named with libxxx.a?

The correct link command is
g++ file1.o file2.o xxx.0 -o target -I./ -I/usr/local/libmylibone/
-L./ -L/usr/local/testlib/ ../lib/special_lib/static_lib.a
-lasn1c++ -lmysqlclient -lnsl -lm -lz -lc -ldl -lpthread -lrt -ljson
Please focus on ../lib/special_lib/static_lib.a, this is a static library and not named with libxxx.a. And I don't know how to write a CMake command to get this correct link command.
I've tried TARGET_LINK_LIBRARIES(../lib/special_lib/static_lib.a) and it will be translated to -l../lib/special_lib/static_lib.a. I've also tried TARGET_LINK_LIBRARIES(static_lib) but got -lstatic_lib and failed.
If you put the absolute path to your library it should work:
TARGET_LINK_LIBRARIES(your_binary /usr/local/lib/static_lib.a)
Second option:
ADD_LIBRARY(staticlib STATIC IMPORTED)
SET_TARGET_PROPERTIES(staticlib PROPERTIES IMPORTED_LOCATION /usr/local/lib/static_lib.a)
TARGET_LINK_LIBRARIES(your_binary staticlib)
The official CMake documentation for importing/exporting targets is here.