Linking problem with qrcodegencpp [Linux]

Installing a new library and future its compilation is always pain for me.
I've just installed simple lib: https://www.nayuki.io/page/qr-code-generator-library
It looks like all I need to run command "make" to install this lib.
The Makefile inside:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# ---- Configuration options ----

# External/implicit variables:
# - CXX: The C++ compiler, such as g++ or clang++.
# - CXXFLAGS: Any extra user-specified compiler flags (can be blank).

# Recommended compiler flags:
CXXFLAGS += -std=c++11 -O

# Extra flags for diagnostics:
# CXXFLAGS += -g -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -fsanitize=undefined,address


# ---- Controlling make ----

# Clear default suffix rules
.SUFFIXES:

# Don't delete object files
.SECONDARY:

# Stuff concerning goals
.DEFAULT_GOAL = all
.PHONY: all clean


# ---- Targets to build ----

LIB = qrcodegencpp
LIBFILE = lib$(LIB).a
LIBOBJ = qrcodegen.o
MAINS = QrCodeGeneratorDemo

# Build all binaries
all: $(LIBFILE) $(MAINS)

# Delete build output
clean:
	rm -f -- $(LIBOBJ) $(LIBFILE) $(MAINS:=.o) $(MAINS)
	rm -rf .deps

# Executable files
%: %.o $(LIBFILE)
	$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $< -L . -l $(LIB)

# The library
$(LIBFILE): $(LIBOBJ)
	$(AR) -crs $@ -- $^

# Object files
%.o: %.cpp .deps/timestamp
	$(CXX) $(CXXFLAGS) -c -o $@ -MMD -MF .deps/$*.d $<

# Have a place to store header dependencies automatically generated by compiler
.deps/timestamp:
	mkdir -p .deps
	touch .deps/timestamp

# Make use of said dependencies if available
-include .deps/*.d */



The output is:

make
mkdir -p .deps
touch .deps/timestamp
g++ -std=c++11 -O -c -o qrcodegen.o -MMD -MF .deps/qrcodegen.d qrcodegen.cpp
ar -crs libqrcodegencpp.a -- qrcodegen.o
g++ -std=c++11 -O -c -o QrCodeGeneratorDemo.o -MMD -MF .deps/QrCodeGeneratorDemo.d QrCodeGeneratorDemo.cpp
g++ -std=c++11 -O  -o QrCodeGeneratorDemo QrCodeGeneratorDemo.o -L . -l qrcodegencpp


Okay, done!

Now, I'm tring to compile my program (with #include </home/spistol/qrcodegencpp/qrcodegen.hpp>) but have no luck:

g++ qr-codegen.cpp -o qr -I /home/spistol/qrcodegencpp -L/usr/lib -lqrcodegencpp
/usr/bin/ld: cannot find -lqrcodegencpp: No such file or directory
collect2: error: ld returned 1 exit status


I've tried as well -lqrcodegen


Or like this:

g++ qr-codegen.cpp -o qr -I /home/spistol/qrcodegencpp -L/usr/lib
/usr/bin/ld: /tmp/ccyBJRsY.o: in function `generateQRCode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
qr-codegen.cpp:(.text+0x30): undefined reference to `qrcodegen::QrCode::encodeText(char const*, qrcodegen::QrCode::Ecc)'
/usr/bin/ld: qr-codegen.cpp:(.text+0x3c): undefined reference to `qrcodegen::QrCode::getSize() const'
/usr/bin/ld: qr-codegen.cpp:(.text+0x71): undefined reference to `qrcodegen::QrCode::getModule(int, int) const'
collect2: error: ld returned 1 exit status



btw:

locate qrcodegen
/usr/lib/libreoffice/share/config/soffice.cfg/cui/ui/qrcodegen.ui
/usr/lib/x86_64-linux-gnu/libqrcodegencpp.so.1
/usr/lib/x86_64-linux-gnu/libqrcodegencpp.so.1.8.0
/usr/share/doc/libqrcodegencpp1
/usr/share/doc/libqrcodegencpp1/changelog.Debian.gz
/usr/share/doc/libqrcodegencpp1/copyright
/var/cache/apt/archives/libqrcodegencpp1_1.8.0-1.2_amd64.deb
/var/lib/dpkg/info/libqrcodegencpp1:amd64.list
/var/lib/dpkg/info/libqrcodegencpp1:amd64.md5sums
/var/lib/dpkg/info/libqrcodegencpp1:amd64.shlibs
/var/lib/dpkg/info/libqrcodegencpp1:amd64.symbols
/var/lib/dpkg/info/libqrcodegencpp1:amd64.triggers


Please suggest what is wrong there?
It sounds like qrcodegencpp is not properly installed on your system. (You ran sudo make install after compiling it, right?

Take a look here (https://unix.stackexchange.com/a/707861/451669) to try to fix it.


The other option is to make sure you have the local .so (that you compiled) in your library path:

 
g++ ... -L ~/qrcodegencpp/bin/ ... -lqrcodegencpp ...

(Or ~/qrcodegencpp/lib/ or wherever it is...)

This shouldn’t be a problem, as you are linking the header files from your local directories as well.


(The other other option would be just to specify its full path when linking):
 
g++ ... /usr/lib/x86_64-linux-gnu/libqrcodegencpp.so.1 ...


(And you really should have a soft link somewhere for just libqrcodegencpp.so which properly redirects to the versioned name of the library.)

Good luck!
Last edited on
> ar -crs libqrcodegencpp.a -- qrcodegen.o
Your compiled library is a .a file, not a .so file.

> /usr/lib/x86_64-linux-gnu/libqrcodegencpp.so.1
This one looks like it was installed when you installed the up-stream version of the code. I don't know why this one doesn't resolve your symbols.

Anyway...

> g++ qr-codegen.cpp -o qr -I /home/spistol/qrcodegencpp -L/usr/lib -lqrcodegencpp

The -L path needs to be where your libqrcodegencpp.a is located.
to Duthomhas, thank you, but "sudo make install" gives just:
make: *** No rule to make target 'install'.  Stop.

There are simple Makefile. I had mentioned path to common folder /usr/lib/ but nothing works without ".a" file.

to salem c, thank you, this rule -L to path where libqrcodegencpp.a is located works correct. So, the final command is:
g++ qr-codegen.cpp -o qr -I /home/spistol/qrcodegencpp -L/home/spistol/qrcodegencpp -lqrcodegencpp


Thank you!
>> /usr/lib/x86_64-linux-gnu/libqrcodegencpp.so.1
> This one looks like it was installed when you installed the up-stream version of the code.

On some distros package management has library split into "runtime" and "development" files.

The runtime is needed for running programs that have been built to use the library and contain, for example libz.so.1.2.11 and symlink libz.so.1 that points to the former. The dynamic linker does seek the libz.so.1 when one starts executable.

The development has headers (e.g. zlib.h) and symlink libz.so that points to libz.so.1.2.11. The -lz makes linker seek the libz.so.

---

The "source build" of "qrcodegencpp" shows that it does not generate .so, but static .a. The linker, rather than injecting instructions for dynamic linker, does import object code from .a into the executable. The -lqrcodegencpp should work nevertheless.
Topic archived. No new replies allowed.