I'm quite new to C++/CMake and was trying to create a CMake file that would compile a GRPC project. I can generate the client (only want client) files fine using this CMake, but I'm trying to create another file (base.cpp
) that will import a class (ManagerClient
) from one of these files. I decided to create a header file for this file I want called manager_client.h
.
I wasn't too sure where in the CMake file to compile base.cpp
so added it as one the target directories and assumed the header file I made would get automatically linked. After running make
, I am getting this error:
Undefined symbols for architecture x86_64:
"ManagerClient::ManagerClient(std::__1::shared_ptr<grpc::Channel>)", referenced from:
ReadUntilClient::ReadUntilClient() in base.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [base] Error 1
make[1]: *** [CMakeFiles/base.dir/all] Error 2
make: *** [all] Error 2
I found this question, but didn't really explain how I could resolve my issue. The strange thing is prior to making base.cpp
, I was able to run base.cpp
logic inside manager_client.cpp
's main function without any issue, so I'm suspecting either I'm compiling it wrong via CMake or my header file is wrong. Any ideas where it's coming from?
Here is the code:
manager_client.cpp
#include <grpcpp/grpcpp.h>
#include <grpc/grpc.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/security/credentials.h>
#include <string>
#include <memory>
#include "minknow_api/manager.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using grpc::ClientReader;
using minknow_api::manager::ManagerService;
using minknow_api::manager::FlowCellPositionsRequest;
using minknow_api::manager::FlowCellPositionsResponse;
class ManagerClient {
public:
ManagerClient(std::shared_ptr<Channel> channel) : stub_(ManagerService::NewStub(channel)) {}
std::unique_ptr<ClientReader<FlowCellPositionsResponse> > flow_cell_positions(FlowCellPositionsRequest request) {
ClientContext context;
return stub_->flow_cell_positions(&context, request);
}
private:
std::unique_ptr<ManagerService::Stub> stub_;
};
int main(int argc, char* argv[]) {
return 0;
}
manager_client.h
#pragma once
#include <grpcpp/grpcpp.h>
#include <grpc/grpc.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/security/credentials.h>
#include <string>
#include <memory>
#include "minknow_api/manager.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using grpc::ClientReader;
using minknow_api::manager::ManagerService;
using minknow_api::manager::FlowCellPositionsRequest;
using minknow_api::manager::FlowCellPositionsResponse;
class ManagerClient {
public:
ManagerClient(std::shared_ptr<Channel> channel);
std::unique_ptr<ClientReader<FlowCellPositionsResponse> > flow_cell_positions(FlowCellPositionsRequest request);
private:
std::unique_ptr<ManagerService::Stub> stub_;
};
base.cpp
#include <grpcpp/grpcpp.h>
#include <grpc/grpc.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/security/credentials.h>
#include <string>
#include <thread>
#include <memory>
#include <iostream>
#include "manager_client.h"
#include "minknow_api/manager.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using grpc::ClientReader;
using minknow_api::manager::FlowCellPositionsRequest;
using minknow_api::manager::FlowCellPositionsResponse;
class ReadUntilClient {
public:
ManagerClient manager;
ReadUntilClient() : manager(grpc::CreateChannel("127.0.0.1:9501",
grpc::InsecureChannelCredentials())) {}
};
int main(int argc, char* argv[]) {
ReadUntilClient client;
return 0;
}
CMakeLists.txt
// Above this I compile the proto files & I only included the code for relevant files
add_library(rg_grpc_proto
${man_grpc_srcs}
${man_grpc_hdrs}
${man_proto_srcs}
${man_proto_hdrs})
target_link_libraries(rg_grpc_proto
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
foreach(_target
manager_client
base)
add_executable(${_target}
"${_target}.cpp")
target_link_libraries(${_target}
rg_grpc_proto
${_REFLECTION}
${_GRPC_GRPCPP}
${_PROTOBUF_LIBPROTOBUF})
endforeach()