1

I want to add the library ixwebsocket my project. Following the instructions of the library I get the libixwebsocket.a (the compiled static library, correct me if I am wrong). How I can use this .a file in my project?

For testing I have created the following program: main.cpp

#CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(cpptest VERSION 0.1.0)

include(CTest)
enable_testing()

add_executable(cpptest main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

target_link_libraries(cpptest "${CMAKE_SOURCE_DIR}/libixwebsocket.a")

//main.cpp
#include <iostream>
#include <ixwebsocket/IXNetSystem.h>
#include <ixwebsocket/IXWebSocket.h>

int main(int, char**) {
    std::cout << "Hello, world!\n";

    ix::WebSocket webSocket;
}

In the directory I have CMakeLists.txt, libixwebsocket.a and main.cpp.

I get a long list of undefined reference errors, the firsts ones:

[build] [ 50%] Linking CXX executable cpptest
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocket.cpp.o): in function `ix::WebSocket::start()':
[build] IXWebSocket.cpp:(.text+0x2240): undefined reference to `pthread_create'
ld] /usr/bin/ld: ../libixwebsocket.a(IXWebSocket.cpp.o): in function `ix::WebSocket::checkConnection(bool)':
[build] IXWebSocket.cpp:(.text+0x5b8d): undefined reference to `pthread_cond_clockwait'
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocketPerMessageDeflateCodec.cpp.o): in function `bool ix::WebSocketPerMessageDeflateCompressor::compressData<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&) [clone .part.0]':
[build] IXWebSocketPerMessageDeflateCodec.cpp:(.text+0x67): undefined reference to `deflate'
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocketPerMessageDeflateCodec.cpp.o): in function `ix::WebSocketPerMessageDeflateCompressor::~WebSocketPerMessageDeflateCompressor()':
[build] IXWebSocketPerMessageDeflateCodec.cpp:(.text+0x35c): undefined reference to `deflateEnd'
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocketPerMessageDeflateCodec.cpp.o): in function `ix::WebSocketPerMessageDeflateCompressor::init(unsigned char, bool)':
[build] IXWebSocketPerMessageDeflateCodec.cpp:(.text+0x3a6): undefined reference to `deflateInit2_'
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocketPerMessageDeflateCodec.cpp.o): in function `ix::WebSocketPerMessageDeflateDecompressor::~WebSocketPerMessageDeflateDecompressor()':
[build] IXWebSocketPerMessageDeflateCodec.cpp:(.text+0x64c): undefined reference to `inflateEnd'
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocketPerMessageDeflateCodec.cpp.o): in function `ix::WebSocketPerMessageDeflateDecompressor::init(unsigned char, bool)':
[build] IXWebSocketPerMessageDeflateCodec.cpp:(.text+0x685): undefined reference to `inflateInit2_'
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocketPerMessageDeflateCodec.cpp.o): in function `ix::WebSocketPerMessageDeflateDecompressor::decompress(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
[build] IXWebSocketPerMessageDeflateCodec.cpp:(.text+0x7d6): undefined reference to `inflate'
[build] /usr/bin/ld: ../libixwebsocket.a(IXWebSocketPerMessageDeflateCodec.cpp.o): in function `bool ix::WebSocketPerMessageDeflateCompressor::compressData<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<unsigned char, std::allocator<unsigned char> >&) [clone .part.0]':
[build] IXWebSocketPerMessageDeflateCodec.cpp:(.text+0x90d): undefined reference to `deflate'
[build] /usr/bin/ld: ../libixwebsocket.a(IXSocketOpenSSL.cpp.o): in function `ix::SocketOpenSSL::openSSLInitialize()':
[build] IXSocketOpenSSL.cpp:(.text+0x1c): undefined reference to `OPENSSL_init_ssl'
[build] /usr/bin/ld: IXSocketOpenSSL.cpp:(.text+0x29): undefined reference to `OPENSSL_init_ssl'

How may these undefined refrence errors be resolved? Thanks in advance!

Quxflux
  • 3,133
  • 2
  • 26
  • 46
DamyHao
  • 15
  • 4
  • Considering its saying you have an undefined reference to a pthread function, I'm going to say you need to also link in pthreads – ChrisMM Jun 30 '21 at 10:17
  • The list of errors is long, if I include pthreads I will have to include a lot of other things – DamyHao Jun 30 '21 at 10:25
  • you'll need to link in ixwebsockets dependencies, see `target_link_libraries` entries at https://github.com/machinezone/IXWebSocket/blob/master/CMakeLists.txt. [Conan](https://conan.io) might make your life easier, there's a ready made recipe for [ixwebsocket](https://conan.io/center/ixwebsocket) – Alan Birtles Jun 30 '21 at 10:37
  • So I will have to include all ```target_link_libraries ``` of the library on my CMakeLists.txt? – DamyHao Jun 30 '21 at 10:48
  • 1
    yep, unless you're using `find_package` or `pkg-config` or a package manager like conan you have to explicitly link to all static library dependencies – Alan Birtles Jun 30 '21 at 10:55
  • How I would use find_package in this case? – DamyHao Jun 30 '21 at 11:24
  • you'd need to see if cmake has built in ixwebsockets find_package support (I don't think it has) or if someone has written a third party find_package module for it – Alan Birtles Jun 30 '21 at 13:56

2 Answers2

1

It would be always best to use find_package() calls. This way you ensure that the library is indeed installed on your system, or is exported in the build tree.

If you have the library installed on your system you can use this call, like this:

find_package(ixwebsocket REQUIRED)
target_link_libraries(cpptest ixwebsocket::ixwebsocket)

In your case, since the library is compiled independently (and it is not a target in your tree), you need to use find_library(IXWEBSOCKET_LIB ixwebsocket) and specify additional hints/names if you have the library in your own location, following the docs.

Celeborth
  • 48
  • 4
  • In my case, I have to use only find_library or both find_package and find_library? Thanks for the answer it has helped me to understand. – DamyHao Jul 01 '21 at 15:15
  • In your case you need to call it as I mentioned above (it is not installed on your system) - `find_library()`. Also if the answer is helpful, please do upvote it or mark it as the answer – Celeborth Jul 01 '21 at 15:30
  • But it is still not working. I have used ```find_library(IXWEBSOCKET_LIB ixwebsocket REQUIRED PATHS "../Llibreries/IXWebSocket/build" NO_DEFAULT_PATH REQUIRED) ``` and I get the same error as before. The solution I have found is to use ```add_subdirectory``` but I think it is not the correct way. – DamyHao Jul 02 '21 at 10:59
  • You should use CMake variables to reference paths, like in [this answer](https://stackoverflow.com/a/15773426/7092926). Also Llibreries looks like a mistake in spelling, please check that. – Celeborth Jul 02 '21 at 12:12
0

I ran into a similar issue today, the library was linking just fine but a static lib is just a collection of .o files and has no understanding of it's own dependencies...

This command worked for me:

g++ -o output/myapp -std=c++17 myapp.cpp -Llib -framework CoreFoundation -framework Security -lmylib

I'm no expert in CMake but this answer seems to indicate that the below would achieve the same effect

target_link_libraries(program "-framework CoreFoundation" "-framework Security")

So if we apply it to your case:

#CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(cpptest VERSION 0.1.0)

include(CTest)
enable_testing()

add_executable(cpptest main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

target_link_libraries(cpptest "${CMAKE_SOURCE_DIR}/libixwebsocket.a" "-framework CoreFoundation")

I've got a feeling pthread_create is likely to live in CoreFoundation but I'm just guessing... You may need to try a few frameworks to find the right one.

Hope this helps a little :)

  • Sorry but maybe I wasn't clear enough. The pthread error is only the first one, I got a list of maybe 100 undefined reference errors – DamyHao Jun 30 '21 at 10:29