Sebastian
Sebastian

Reputation: 15

subdirectory with 3rd party library gets not compiled

I want to use rpclib from here. I started a new project with main.cpp and CMakeLists.txt and copied the rpclib as a subdirectory into my project:

My code is exactly the example from rpclib and looks like this:

#include <iostream>
#include "rpc/server.h"

void foo() {
    std::cout << "foo was called!" << std::endl;
}

int main(int argc, char *argv[]) {
    // Creating a server that listens on port 8080
    rpc::server srv(8080);

    // Binding the name "foo" to free function foo.
    // note: the signature is automatically captured
    srv.bind("foo", &foo);

    // Binding a lambda function to the name "add".
    srv.bind("add", [](int a, int b) {
        return a + b;
    });

    // Run the server loop.
    srv.run();

    return 0;
}

and my CMakeLists.txt looks like this:

cmake_minimum_required(VERSION 3.16)
project(RPC_Test)

set(CMAKE_CXX_STANDARD 14)

add_subdirectory(rpclib)
include_directories(rpclib/include)

add_executable(RPC_Test main.cpp)

As I understood, the line add_subdirectory(rpclib) takes care of adding the rpclib and builds its content during building the RPC_Test-Project. It seems, I am wrong. Nothing within rpclib gets build and the build-process RPC_Test fails with a linker-error:

/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /Users/seba/CLionProjects/rpc-cpp/cmake-build-debug-system --target RPC_Test -- -j 3
Scanning dependencies of target RPC_Test
[ 50%] Building CXX object CMakeFiles/RPC_Test.dir/main.cpp.o
[100%] Linking CXX executable RPC_Test
Undefined symbols for architecture x86_64:
  "rpc::detail::dispatcher::enforce_arg_count(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long)", referenced from:
      void rpc::detail::dispatcher::bind<void (*)()>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void (*)(), rpc::detail::tags::void_result const&, rpc::detail::tags::zero_arg const&)::'lambda'(clmdep_msgpack::v2::object const&)::operator()(clmdep_msgpack::v2::object const&) const in main.cpp.o
      void rpc::detail::dispatcher::bind<main::$_0>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, main::$_0, rpc::detail::tags::nonvoid_result const&, rpc::detail::tags::nonzero_arg const&)::'lambda'(clmdep_msgpack::v2::object const&)::operator()(clmdep_msgpack::v2::object const&) const in main.cpp.o
  "rpc::detail::dispatcher::enforce_unique_name(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      void rpc::detail::dispatcher::bind<void (*)()>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void (*)()) in main.cpp.o
      void rpc::detail::dispatcher::bind<void (*)()>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void (*)(), rpc::detail::tags::void_result const&, rpc::detail::tags::zero_arg const&) in main.cpp.o
      void rpc::detail::dispatcher::bind<main::$_0>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, main::$_0) in main.cpp.o
      void rpc::detail::dispatcher::bind<main::$_0>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, main::$_0, rpc::detail::tags::nonvoid_result const&, rpc::detail::tags::nonzero_arg const&) in main.cpp.o
  "rpc::server::run()", referenced from:
      _main in main.cpp.o
  "rpc::server::server(unsigned short)", referenced from:
      _main in main.cpp.o
  "rpc::server::~server()", referenced from:
      _main in main.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[3]: *** [RPC_Test] Error 1
make[2]: *** [CMakeFiles/RPC_Test.dir/all] Error 2
make[1]: *** [CMakeFiles/RPC_Test.dir/rule] Error 2
make: *** [RPC_Test] Error 2

What is missing?

Upvotes: 0

Views: 252

Answers (1)

Corristo
Corristo

Reputation: 5520

You're missing a target_link_libraries(RPC_Test PRIVATE rpc) after the definition of the RPC_Test target . rpc here is the name of the library target defined in rpclib's CMakeLists.txt, not just the base name of the resulting binary artifact.

When using a target name with target_link_libraries like that CMake will not only add -lrpc to the linker invocation, but also automatically add the include directories necessary to use the library and ensure that the rpc library is built before RPC_Test. In particular, this means you can also remove the include_directories call when you use target_link_libraries(RPC_Test PRIVATE rpc).

Upvotes: 1

Related Questions