How to solve compile error in gRPC generated files? - c++

I am creating client-server application, using gRPC. So far I was not using TLS encryption. Now I want to enable it, and strangely I get this error. It seems, at least to me, that this is a linker error. What would be best ways to solve it?
CLion doesn't highlight anything, so I assumed everything was syntactically OK, but when compiling I got that error.
/usr/bin/ld: CMakeFiles/projectname.dir/main.cpp.o: in function `grpc::SslServerCredentials(grpc::SslServerCredentialsOptions const&)':
/home/username/projectname/third_party/grpc/include/grpcpp/security/server_credentials.h:60: undefined reference to `grpc_impl::SslServerCredentials(grpc::SslServerCredentialsOptions const&)'
collect2: error: ld returned 1 exit status
This is a makefile that I use to generate C++ code from gRPC specification:
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
CPPFLAGS += `pkg-config --cflags protobuf grpc`
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\
-lgrpc++_reflection\
-ldl
else
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
endif
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
PROTOS_PATH = ./
vpath %.proto $(PROTOS_PATH)
%.grpc.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
%.pb.cc: %.proto
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
clean:
rm -f *.o *.pb.cc *.pb.h

Then problem was solved like this:
I had to chage grpc++_unsecure to grpc++ under target_link_libraries in CMakeLists.txt cmake build configuration file.
I had forgotten/not thought about this at first.
target_link_libraries(bita_server
pqxx
sodium
protobuf::libprotobuf
# grpc++_unsecure
grpc++
SQLiteCpp
sqlite3
pthread
dl
${_PROTOBUF_LIBPROTOBUF}
)

In CMakeLists.txt under grpc folder, there are many target_link_libraries. which one to edit in order to include the change.

Related

How to compile DPDK application such as examples to support C++?

How should I modify Makefiles of DPDK to support c++ compilation? I tried by adding CFLAGS += -lstdc++ to the Makefile of the helloworld example but it seems not working. Is there a more standard way to do that?
Edited:
I'm using the makefile of helloworld example in DPDK 20.08 with some small modifications. I'm building it on ubuntu 20.04 ,and which is not cross-compilation. The DPDK is built with dpdk-setup script and not meson. The makefile is
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation
# binary name
APP = rss_helper
# all source are stored in SRCS-y
# SRCS-y := main.c
SRCS-y := test.cpp
# Build using pkg-config variables if possible
ifeq ($(shell pkg-config --exists libdpdk && echo 0),0)
all: shared
# all: static
.PHONY: shared static
shared: build/$(APP)-shared
ln -sf $(APP)-shared build/$(APP)
static: build/$(APP)-static
ln -sf $(APP)-static build/$(APP)
PKGCONF ?= pkg-config
PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)
LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)
build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
$(CC) $(CFLAGS) $(SRCS-y) -o $# $(LDFLAGS) $(LDFLAGS_SHARED)
build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
$(CC) $(CFLAGS) $(SRCS-y) -o $# $(LDFLAGS) $(LDFLAGS_STATIC)
build:
#mkdir -p $#
.PHONY: clean
clean:
rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
test -d build && rmdir -p build || true
else
ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif
# Default target, detect a build directory, by looking for a path with a .config
RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config)))))
include $(RTE_SDK)/mk/rte.vars.mk
CPPFLAGS += -O3
CPPFLAGS += $(WERROR_FLAGS)
CPPFLAGS += -DALLOW_EXPERIMENTAL_API
CPPFLAGS += -lstdc++
include $(RTE_SDK)/mk/rte.extapp.mk
endif
I changed the name of the source file and flags. The source file test.cpp contains only iostream header and an empty main function (just for test). There are two errors:
can't find the test.cpp with cpp on. It works find when replace test.cpp in makefile with test.c while keeping the actual source file name as test.cpp.
LD rss_helper
gcc: error: test.cpp: No such file or directory
make[1]: *** [/home/syk/dpdk-20.08/mk/rte.app.mk:456: rss_helper] Error 1
make: *** [/home/syk/dpdk-20.08/mk/rte.extapp.mk:15: all] Error 2
Error for LD like below
g++ -O3 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wpointer-arith -Wcast-align -Wnested-externs -Wcast-qual -Wformat-nonliteral -Wformat-security -Wundef -Wwrite-strings -Wdeprecated -Wno-missing-field-initializers -Wimplicit-fallthrough=2 -Wno-format-truncation -Wno-address-of-packed-member -DALLOW_EXPERIMENTAL_API -lstdc++ -c -o test.o /home/syk/loadbalancing/rss_helper_demo/test.cpp
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wmissing-prototypes’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wold-style-definition’ is valid for C/ObjC but not for C++
cc1plus: warning: command line option ‘-Wnested-externs’ is valid for C/ObjC but not for C++
LD rss_helper
/usr/bin/ld: test.o: in function `_GLOBAL__sub_I_main':
test.cpp:(.text.startup+0x20): undefined reference to `std::ios_base::Init::Init()'
/usr/bin/ld: test.cpp:(.text.startup+0x27): undefined reference to `std::ios_base::Init::~Init()'
collect2: error: ld returned 1 exit status
make[1]: *** [/home/syk/dpdk-20.08/mk/rte.app.mk:456: rss_helper] Error 1
make: *** [/home/syk/dpdk-20.08/mk/rte.extapp.mk:15: all] Error 2
I tried to resolve it by added -lstdc++ but still had it.
Edited-2:
The source file:
#include <iostream>
#include <rte_eal.h>
using namespace std;
class A{
int a;
};
int
main(void){
return 0;
}
It can't include iostream and rte_eal either.
there are 2 possible ways to solve this issue
set environment set CC=g++. Then execute make
edit Makefile to add CC = g++
with these changes I am able build and run the sample code.
linux-vdso.so.1 (0x00007fff0a3e6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1389440000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f138904f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1388cb1000)
/lib64/ld-linux-x86-64.so.2 (0x00007f13899cb000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1388a99000)
and
ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6e3fb6ed5f48b8f66fe4c05118f7b6bf6a9a1235, not stripped
You need to modify the makefile inorder to adapt C++:
You need to change CFLAGS to CPPFLAGS
See below reference example:
ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif
# Default target, can be overriden by command line or environment
RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
# binary name
APP = dpdkrecv
# all source are stored in SRCS-y
SRCS-y := main.c syncshm.c cqf.cpp countingquotientfilter.cpp murmurhash3.cpp
CPPFLAGS += -O3 -mbmi2
CFLAGS += $(WERROR_FLAGS)
include $(RTE_SDK)/mk/rte.extapp.mk
Please share the Makefile,
I am adding
#include algorithm
dpdk ver: dpdk-stable-18.11.2 ,
build with
sudo make install T=x86_64-native-linuxapp-gcc DESTDIR=install

Compiling GRPC C++ service statically

I am trying to deploy a C++ GRPC server on docker. Unfortunately, the grpc examples use dynamically linked GRPC libraries. When copying the executables to docker (e.g. a small alpine based one) it responds "not found". The underlying problem is that the executable depends on dynamically linked GRPC libraries.
I updated the example Makefile of GRPC to [only change is adding -static]
HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
SYSTEM ?= $(HOST_SYSTEM)
CXX = g++
CPPFLAGS += `pkg-config --cflags protobuf grpc`
CXXFLAGS += -std=c++11
ifeq ($(SYSTEM),Darwin)
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-lgrpc++_reflection\
-ldl
else
LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
-Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
-ldl
endif
PROTOC = protoc
GRPC_CPP_PLUGIN = grpc_cpp_plugin
GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
PROTOS_PATH = ../../protos
vpath %.proto $(PROTOS_PATH)
all: system-check greeter_client greeter_server greeter_async_client greeter_async_client2 greeter_async_server
greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
$(CXX) $^ $(LDFLAGS) -o $# -static
However, this runs into
Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x43d): undefined reference to `deflateInit2_'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x44e): undefined reference to `deflate'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x4bb): undefined reference to `deflateEnd'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x5bc): undefined reference to `inflateInit2_'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x5cb): undefined reference to `inflate'
/usr/local/lib/libgrpc.a(message_compress.o):(.text+0x63b): undefined reference to `inflateEnd'
How can I adjust this to get a working statically compiled GRPC client / server?
You are missing link compress library, using -lz to fix this bug.

lopencv_core not found when using opencv

I have opencv3 installed through home-brew and pkg-config can find the linkers too by
pkg-config --cflags --libs opencv
the outputs contains -lopencv_core, but when I add that in Makefile like this
CC=clang++
CFLAGS= -Wall -g -std=c++0x
LFLAGS= -I/usr/local/Cellar/opencv3/3.2.0/include -I/usr/local/Cellar/opencv3/3.2.0/bin -I/usr/local/Cellar/opencv3/3.2.0/lib -lopencv_core
CFILES=blah.cpp
HFILES=blah.hpp
OFILES=blah.o
all: main
%.o: %.cpp $(HFILES)
$(CC) -c $(CFLAGS) $< -o $# $(LFLAGS)
main: $(OFILES) $(HFILES)
$(CC) $(CFLAGS) $(OFILES) -o main $(LFLAGS)
it says
ld: library not found for -lopencv_core
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How should I link that to gcc?
Assuming you want CFLAGS to be the options for compilation and LFLAGS to
be the options for linkage, the settings:
CFLAGS= -Wall -g -std=c++0x
LFLAGS= -I/usr/local/Cellar/opencv3/3.2.0/include -I/usr/local/Cellar/opencv3/3.2.0/bin -I/usr/local/Cellar/opencv3/3.2.0/lib -lopencv_core
are confused.
The -I path option is meaningful for compilation and meaningless for linkage. It
tells the preprocessor to search in path for header files that you #include in
the source code. There will be header files in:
/usr/local/Cellar/opencv3/3.2.0/include
There will be no header files in:
/usr/local/Cellar/opencv3/3.2.0/bin
just executables, which are irrelevant to building your program. And there will be no header files in:
/usr/local/Cellar/opencv3/3.2.0/lib
just static and or dynamic libraries.
The library libopencv_core that linker can't find is presumably
in /usr/local/Cellar/opencv3/3.2.0/lib. The way to tell the
linker to search there for the library is:
-L/usr/local/Cellar/opencv3/3.2.0/lib -lopencv_core
So these settings make sense:
CFLAGS := -Wall -g -std=c++0x -I/usr/local/Cellar/opencv3/3.2.0/include
LFLAGS := -L/usr/local/Cellar/opencv3/3.2.0/lib -lopencv_core
However, to compile and link an opencv program you would probably be better
leaving it to pkg-config to get the options right:
CFLAGS := -Wall -g -std=c++0x $(shell pkg-config --cflags opencv)
LFLAGS := $(shell pkg-config --libs opencv)
The -l option looks in the usual places for the mentioned library. Where and what it looks varies by OS, which you didn't mention. Possibly it can be fixed by adding -L /usr/local/lib or some other path to where you know the libraries are.

How should I link to LLVM libraries?

When I use command "gcc .. ../../*.so", there are the following error messages:
/usr/bin/ld: /home/demonwnb/build/src/*.so: error: undefined reference to 'llvm::raw_ostream::operator<<(void const*)'
/usr/bin/ld: /home/demonwnb/build/src/*.so: error: undefined reference to 'clang::DeclarationName::printName(llvm::raw_ostream&) const'
I think that I do not link "llvm library" correctly, so how should I do?
You need to tell your compiler where to load the libraries from, which can be done using the llvm-config command.
You could set the following symbols in your makefile
CC = g++
LLVM_MODULES = core jit native
CPPFLAGS = `llvm-config --cppflags $(LLVM_MODULES)`
LDFLAGS = `llvm-config --ldflags $(LLVM_MODULES)`
LIBS = `llvm-config --libs $(LLVM_MODULES)`
all:
$(CC) *.o $(LDFLAGS) $(LIBS) -o MyOutput
main:
find -name '*.cpp' -print0 | xargs -0 $(CC) -c $(CPPFLAGS)
Did you try using g++ to do the link? Those are C++ libraries and gcc doesn't pass the C++ libraries to the linker.

Problem using yaml-cpp on OS X

So I'm having trouble compiling my application which is using yaml-cpp
I'm including "yaml.h" in my source files (just like the examples in the yaml-cpp wiki) but when I try compiling the application I get the following error:
g++ -c -o entityresourcemanager.o entityresourcemanager.cpp
entityresourcemanager.cpp:2:18: error: yaml.h: No such file or directory
make: *** [entityresourcemanager.o] Error 1
my makefile looks like this:
CC = g++
CFLAGS = -Wall
APPNAME = game
UNAME = uname
OBJECTS := $(patsubst %.cpp,%.o,$(wildcard *.cpp))
mac: $(OBJECTS)
$(CC) `pkg-config --cflags --libs sdl` `pkg-config --cflags --libs yaml-cpp` $(CFLAGS) -o $(APPNAME) $(OBJECTS)
pkg-config --cflags --libs yaml-cpp returns:
-I/usr/local/include/yaml-cpp -L/usr/local/lib -lyaml-cpp
and yaml.h is indeed located in /usr/local/include/yaml-cpp
Any idea what I could do?
Thanks
Your default target is "mac" and you have rule how to build it. It depends on object files and you do not have any rules how to build those, so make is using its implicit rules. Those rules do just that:
g++ -c -o entityresourcemanager.o entityresourcemanager.cpp
As you can see there is no -I/usr/local/... part here.
The easiest way to fix that is to change CPPFLAGS and LDFLAGS value globally:
YAML_CFLAGS := $(shell pkg-config --cflags yaml-cpp)
YAML_LDFLAGS := $(shell pkg-config --libs yaml-cpp)
SDL_CFLAGS := $(shell pkg-config --cflags sdl)
SDL_LDFLAGS := $(shell pkg-config --libs sdl)
CPPFLAGS += $(YAML_CFLAGS) $(SDL_CFLAGS)
LDFLAGS += $(YAML_LDFLAGS) $(SDL_LDFLAGS)
mac: $(OBJECTS)
$(CXX) -o $(APPNAME) $(OBJECTS) $(LDFLAGS)
CPPFLAGS value is used by implicit rules that build object files from cpp files, so now compiler should find yaml headers.
Edit:
LDFLAGS probably should go after OBJECTS
Don't you mismatch your include directory?
-I/usr/local/include
instead of
-I/usr/local/include/yaml-cpp