Setup ubuntu Multipass Environment

Hi All, Just getting going with libzt, I have installed as per the tutorial and set up my dev dependencies./tools make and cmake etc in my multipass and compiled all successfully. I am getting a little confused on how to compile the examples supplied, this is to make sure I have my environment setup correctly.

  gcc pingable-node.c -o pingable-node
/usr/bin/ld: /tmp/ccYNJhze.o: in function `main':
pingable-node.c:(.text+0x8f): undefined reference to `zts_node_start'
/usr/bin/ld: pingable-node.c:(.text+0xa7): undefined reference to `zts_util_delay'
/usr/bin/ld: pingable-node.c:(.text+0xb1): undefined reference to `zts_node_is_online'
/usr/bin/ld: pingable-node.c:(.text+0xbf): undefined reference to `zts_node_get_id'
/usr/bin/ld: pingable-node.c:(.text+0x123): undefined reference to `zts_node_get_id_pair'
/usr/bin/ld: pingable-node.c:(.text+0x178): undefined reference to `zts_net_join'
/usr/bin/ld: pingable-node.c:(.text+0x1aa): undefined reference to `zts_util_delay'
/usr/bin/ld: pingable-node.c:(.text+0x1b9): undefined reference to `zts_net_transport_is_ready'
/usr/bin/ld: pingable-node.c:(.text+0x1df): undefined reference to `zts_util_delay'
/usr/bin/ld: pingable-node.c:(.text+0x1f3): undefined reference to `zts_addr_is_assigned'
/usr/bin/ld: pingable-node.c:(.text+0x26c): undefined reference to `zts_addr_get_str'
/usr/bin/ld: pingable-node.c:(.text+0x298): undefined reference to `zts_util_delay'
collect2: error: ld returned 1 exit status

I have set up ~/projects/libzt etc. what’s the best way to make sure that when compiling all my libraries and header structures are picked up, is there any tutorials on setting env paths? if so can someone please post a link so I can start my journey on compiling libzt.

thanks in advance for any pointers or assistance.

Just tested on Ubuntu and was able to replicate your issue. It’s a linker argument order error. They’re rare but they happen.

Install with:

brew install zerotier/tap/libzt

And then, change:

clang++ /home/linuxbrew/.linuxbrew/Cellar/libzt/1.4.1/lib/libzt.a -I/home/linuxbrew/.linuxbrew/Cellar/libzt/1.4.1/include pingable-node.c -lpthread -o pn

to

clang++ pingable-node.c -o pn /home/linuxbrew/.linuxbrew/Cellar/libzt/1.4.1/lib/libzt.a -I/home/linuxbrew/.linuxbrew/Cellar/libzt/1.4.1/include -lpthread

I’ll update the docs. Let me know if you run into any other issues.

Hey Joseph, many thanks for clarifying, I thought it was something I hadn’t set, I will change and report back. looking to do some stuff on espressif ove rhere.

Nice. And no problem.

As far as I know Espressif’s SoCs might be too weak to run ZT, but I’ve never tried. Let me know if you run into any blockers and I can try to help.

What is your target chip?

I am looking at a couple, ESP32, ESP-EYE etc I have had some success with other libraries, i can see that the compiled state is 2mb with a basic and it maybe too heavy, I have block chain app that does work to setup encrypted sessions. Once I can understand the libs I am thinking I could strip some stuff back and create a new layer. I will have a good team to support me soon and hope to release it back to this area. I like what your doing and have run the lonely path, but then again innovation is hard.

I tried what you suggested and got the following error

        clang pingable-node.c -o pn ~/projects/libzt/dist/linux-x64-host-release/lib/libzt.a -I ~/projects/libzt/dist/linux-x64-host-release/include -lpthread
        pingable-node.c:7:10: fatal error: 'ZeroTierSockets.h' file not found
        #include "ZeroTierSockets.h"
                 ^~~~~~~~~~~~~~~~~~~
        1 error generated.

I changed for my paths and clang not clang++. hope it helps

If you aren’t installing via brew your header would be in ~/projects/libzt/include

Also, I think the biggest hurdle to ZT running on an espressif chip will be the crypto load. We do have an AES option in 1.6.X but that will be available in a couple of weeks.

Do you know if your chip supports hardware AES?

If it doesn’t you’re likely to see ZT run at an unimaginably slow speed unless crypto is disabled altogether in a forked build.

Hi Joseph, I will take a look at mac for compiling. They support AES to an extent but am looking at a bespoke approach with ed25519 but first need to see how I can strip back the library.

bespoke approach with ed25519

I wish you luck!

I’m not sure of your level of experience so don’t take this personally if I’m saying something that you already know, but you will need a cross-compiler of some sort to target the ESP32 if you’re building on a regular desktop machine running linux/mac.

Hi Joseph, no offence taken mate, I am a telecom guy and its been a while soince I did some coding, but I have a goos team, I am more on architecture and trying to understand. I have ahd really good succes with atom and object identification libs etc…

Btw, there’s an open github ticket on our zerotierone repo talking about ZT on ESP32: REQ: zerotier on ESP32 or other 'arduino' like hardware · Issue #668 · zerotier/ZeroTierOne · GitHub

Feel free to inquire there as well since there seem to be people that might know things and I’m sure they’d be interesting in knowing that you got it to work if you did.

1 Like

thanks Joseph, looking forward to pushing some PR your way…

1 Like

Hi Joseph, just an update when running through the tutorial from mac and removing multipass etc

Trying to build the pingable-node.c example I get the errors below. I tried the clang++ example you gave and put the errors for that after the gcc example.
`gcc pingable-node.c -o pingable-node
Undefined symbols for architecture x86_64:
“_zts_addr_get_str”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_addr_is_assigned”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_net_join”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_net_transport_is_ready”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_node_get_id”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_node_get_id_pair”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_node_is_online”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_node_start”, referenced from:
_main in pingable-node-3e3e30.o
“_zts_util_delay”, referenced from:
_main in pingable-node-3e3e30.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)’

path is ~/libzt

clang++ pingable-node.c -o pn /usr/local/Cellar/libzt/1.4.1/lib/libzt.a -I/usr/local/Cellar/libzt/libzt/1.4.1/include -lpthread

Homebrew installed libzt into a different path from you as shown above.

clang: warning: treating ‘c’ input as ‘c++’ when in C++ mode, this behavior is deprecated [-Wdeprecated]

with clang

clang pingable-node.c -o pn /usr/local/Cellar/libzt/1.4.1/lib/libzt.a -I/usr/local/Cellar/libzt/libzt/1.4.1/include -lpthread
Undefined symbols for architecture x86_64:
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::rfind(char, unsigned long) const", referenced from:
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::compare(unsigned long, unsigned long, char const*, unsigned long) const", referenced from:
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      ZeroTier::PortMapperImpl::threadMain() in libzt.a(PortMapper.cpp.o)
  "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
      std::__1::vector<ZeroTier::World::Root, std::__1::allocator<ZeroTier::World::Root> >::push_back(ZeroTier::World::Root&&) in libzt.a(Utilities.cpp.o)
      std::__1::vector<ZeroTier::InetAddress, std::__1::allocator<ZeroTier::InetAddress> >::push_back(ZeroTier::InetAddress&&) in libzt.a(Utilities.cpp.o)
      std::__1::enable_if<(__is_cpp17_forward_iterator<ZeroTier::World::Root*>::value) && (is_constructible<ZeroTier::World::Root, std::__1::iterator_traits<ZeroTier::World::Root*>::reference>::value), void>::type std::__1::vector<ZeroTier::World::Root, std::__1::allocator<ZeroTier::World::Root> >::assign<ZeroTier::World::Root*>(ZeroTier::World::Root*, ZeroTier::World::Root*) in libzt.a(Utilities.cpp.o)
      std::__1::vector<ZeroTier::World::Root, std::__1::allocator<ZeroTier::World::Root> >::__vallocate(unsigned long) in libzt.a(Utilities.cpp.o)
      std::__1::enable_if<(__is_cpp17_forward_iterator<ZeroTier::InetAddress*>::value) && (is_constructible<ZeroTier::InetAddress, std::__1::iterator_traits<ZeroTier::InetAddress*>::reference>::value), void>::type std::__1::vector<ZeroTier::InetAddress, std::__1::allocator<ZeroTier::InetAddress> >::assign<ZeroTier::InetAddress*>(ZeroTier::InetAddress*, ZeroTier::InetAddress*) in libzt.a(Utilities.cpp.o)
      std::__1::vector<ZeroTier::InetAddress, std::__1::allocator<ZeroTier::InetAddress> >::__vallocate(unsigned long) in libzt.a(Utilities.cpp.o)
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      ...
  "std::__1::__basic_string_common<true>::__throw_length_error() const", referenced from:
      _zts_id_new in libzt.a(Controls.cpp.o)
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*) in libzt.a(NodeService.cpp.o)
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::operator+<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*) in libzt.a(NodeService.cpp.o)
      ZeroTier::VirtualTap::VirtualTap(char const*, ZeroTier::MAC const&, unsigned int, unsigned int, unsigned long long, void (*)(void*, void*, unsigned long long, ZeroTier::MAC const&, ZeroTier::MAC const&, unsigned int, unsigned int, void const*, unsigned int), void*) in libzt.a(VirtualTap.cpp.o)
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*) in libzt.a(OSUtils.cpp.o)
      ZeroTier::PortMapperImpl::PortMapperImpl(int, char const*) in libzt.a(PortMapper.cpp.o)
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*) in libzt.a(Peer.cpp.o)
      ...
  "std::logic_error::logic_error(char const*)", referenced from:
      std::length_error::length_error(char const*) in libzt.a(Utilities.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(NodeService.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(VirtualTap.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(OSUtils.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(PortMapper.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(Node.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(Multicaster.cpp.o)
      ...
  "std::length_error::~length_error()", referenced from:
      std::__1::__throw_length_error(char const*) in libzt.a(Utilities.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(NodeService.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::OSUtils::ztsnprintf(char*, unsigned int, char const*, ...) in libzt.a(OSUtils.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(OSUtils.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(PortMapper.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(Node.cpp.o)
      ...
  "std::runtime_error::runtime_error(char const*)", referenced from:
      ZeroTier::Phy<ZeroTier::NodeService*>::Phy(ZeroTier::NodeService*, bool, bool) in libzt.a(NodeService.cpp.o)
      ZeroTier::Thread ZeroTier::Thread::start<ZeroTier::VirtualTap>(ZeroTier::VirtualTap*) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::Phy<ZeroTier::VirtualTap*>::Phy(ZeroTier::VirtualTap*, bool, bool) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::Thread ZeroTier::Thread::start<ZeroTier::PortMapperImpl>(ZeroTier::PortMapperImpl*) in libzt.a(PortMapper.cpp.o)
  "std::runtime_error::~runtime_error()", referenced from:
      ZeroTier::Phy<ZeroTier::NodeService*>::Phy(ZeroTier::NodeService*, bool, bool) in libzt.a(NodeService.cpp.o)
      ZeroTier::Thread ZeroTier::Thread::start<ZeroTier::VirtualTap>(ZeroTier::VirtualTap*) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::Phy<ZeroTier::VirtualTap*>::Phy(ZeroTier::VirtualTap*, bool, bool) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::Thread ZeroTier::Thread::start<ZeroTier::PortMapperImpl>(ZeroTier::PortMapperImpl*) in libzt.a(PortMapper.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*)", referenced from:
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      ZeroTier::OSUtils::rmDashRf(char const*) in libzt.a(OSUtils.cpp.o)
      ZeroTier::NetworkConfig::toDictionary(ZeroTier::Dictionary<419456u>&, bool) const in libzt.a(NetworkConfig.cpp.o)
      ZeroTier::CertificateOfMembership::toString() const in libzt.a(CertificateOfMembership.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*, unsigned long)", referenced from:
      _zts_util_sign_root_set in libzt.a(Utilities.cpp.o)
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > std::__1::operator+<char, std::__1::char_traits<char>, std::__1::allocator<char> >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*) in libzt.a(NodeService.cpp.o)
      ZeroTier::OSUtils::readFile(char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) in libzt.a(OSUtils.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*)", referenced from:
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      ZeroTier::NodeService::phyOnDatagram(void*, void**, sockaddr const*, sockaddr const*, void*, unsigned long) in libzt.a(NodeService.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::push_back(char)", referenced from:
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      ZeroTier::OSUtils::rmDashRf(char const*) in libzt.a(OSUtils.cpp.o)
      ZeroTier::OSUtils::split(char const*, char const*, char const*, char const*) in libzt.a(OSUtils.cpp.o)
      ZeroTier::NetworkConfig::toDictionary(ZeroTier::Dictionary<419456u>&, bool) const in libzt.a(NetworkConfig.cpp.o)
      ZeroTier::CertificateOfMembership::toString() const in libzt.a(CertificateOfMembership.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      ZeroTier::NodeService::fatalErrorMessage() const in libzt.a(NodeService.cpp.o)
      std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::push_back(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libzt.a(OSUtils.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long, std::__1::allocator<char> const&)", referenced from:
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
      ZeroTier::NodeService::~NodeService() in libzt.a(NodeService.cpp.o)
      ZeroTier::VirtualTap::~VirtualTap() in libzt.a(VirtualTap.cpp.o)
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator=(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
      _zts_util_sign_root_set in libzt.a(Utilities.cpp.o)
  "std::bad_alloc::bad_alloc()", referenced from:
      ZeroTier::Node::Node(void*, void*, ZT_Node_Callbacks const*, long long) in libzt.a(Node.cpp.o)
  "std::bad_alloc::~bad_alloc()", referenced from:
      ZeroTier::Node::Node(void*, void*, ZT_Node_Callbacks const*, long long) in libzt.a(Node.cpp.o)
  "std::terminate()", referenced from:
      ___clang_call_terminate in libzt.a(Controls.cpp.o)
      ___clang_call_terminate in libzt.a(Utilities.cpp.o)
      ___clang_call_terminate in libzt.a(NodeService.cpp.o)
      ___clang_call_terminate in libzt.a(VirtualTap.cpp.o)
      ___clang_call_terminate in libzt.a(Utils.cpp.o)
      ___clang_call_terminate in libzt.a(Identity.cpp.o)
      ___clang_call_terminate in libzt.a(PortMapper.cpp.o)
      ...
  "typeinfo for std::length_error", referenced from:
      std::__1::__throw_length_error(char const*) in libzt.a(Utilities.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(NodeService.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::OSUtils::ztsnprintf(char*, unsigned int, char const*, ...) in libzt.a(OSUtils.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(OSUtils.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(PortMapper.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(Node.cpp.o)
      ...
  "typeinfo for std::runtime_error", referenced from:
      ZeroTier::Phy<ZeroTier::NodeService*>::Phy(ZeroTier::NodeService*, bool, bool) in libzt.a(NodeService.cpp.o)
      ZeroTier::Thread ZeroTier::Thread::start<ZeroTier::VirtualTap>(ZeroTier::VirtualTap*) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::Phy<ZeroTier::VirtualTap*>::Phy(ZeroTier::VirtualTap*, bool, bool) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::Thread ZeroTier::Thread::start<ZeroTier::PortMapperImpl>(ZeroTier::PortMapperImpl*) in libzt.a(PortMapper.cpp.o)
      GCC_except_table42 in libzt.a(Node.cpp.o)
  "typeinfo for std::bad_alloc", referenced from:
      ZeroTier::Node::Node(void*, void*, ZT_Node_Callbacks const*, long long) in libzt.a(Node.cpp.o)
      GCC_except_table42 in libzt.a(Node.cpp.o)
      GCC_except_table44 in libzt.a(Node.cpp.o)
      GCC_except_table45 in libzt.a(Node.cpp.o)
      GCC_except_table46 in libzt.a(Node.cpp.o)
      GCC_except_table47 in libzt.a(Node.cpp.o)
      GCC_except_table48 in libzt.a(Node.cpp.o)
      ...
  "typeinfo for std::exception", referenced from:
      GCC_except_table13 in libzt.a(NodeService.cpp.o)
  "typeinfo for int", referenced from:
      void ZeroTier::World::serialize<8480u>(ZeroTier::Buffer<8480u>&, bool) const in libzt.a(Utilities.cpp.o)
      unsigned int ZeroTier::World::deserialize<8480u>(ZeroTier::Buffer<8480u> const&, unsigned int) in libzt.a(Utilities.cpp.o)
      ZeroTier::Identity::Identity(char const*) in libzt.a(Utilities.cpp.o)
      void ZeroTier::Identity::serialize<8480u>(ZeroTier::Buffer<8480u>&, bool) const in libzt.a(Utilities.cpp.o)
      void ZeroTier::InetAddress::serialize<8480u>(ZeroTier::Buffer<8480u>&) const in libzt.a(Utilities.cpp.o)
      ZeroTier::Buffer<8480u>::operator[](unsigned int) const in libzt.a(Utilities.cpp.o)
      ZeroTier::Buffer<8480u>::field(unsigned int, unsigned int) const in libzt.a(Utilities.cpp.o)
      ...
  "vtable for __cxxabiv1::__class_type_info", referenced from:
      typeinfo for moodycamel::details::ConcurrentQueueProducerTypelessBase in libzt.a(Events.cpp.o)
      typeinfo for ZeroTier::NetworkController::Sender in libzt.a(Node.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for __cxxabiv1::__si_class_type_info", referenced from:
      typeinfo for moodycamel::ConcurrentQueue<zts_event_msg_t*, moodycamel::ConcurrentQueueDefaultTraits>::ExplicitProducer in libzt.a(Events.cpp.o)
      typeinfo for moodycamel::ConcurrentQueue<zts_event_msg_t*, moodycamel::ConcurrentQueueDefaultTraits>::ImplicitProducer in libzt.a(Events.cpp.o)
      typeinfo for ZeroTier::Node in libzt.a(Node.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for __cxxabiv1::__vmi_class_type_info", referenced from:
      typeinfo for moodycamel::ConcurrentQueue<zts_event_msg_t*, moodycamel::ConcurrentQueueDefaultTraits>::ProducerBase in libzt.a(Events.cpp.o)
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "vtable for std::length_error", referenced from:
      std::length_error::length_error(char const*) in libzt.a(Utilities.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(NodeService.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(VirtualTap.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(OSUtils.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(PortMapper.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(Node.cpp.o)
      std::length_error::length_error(char const*) in libzt.a(Multicaster.cpp.o)
      ...
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "operator delete[](void*)", referenced from:
      ZeroTier::Identity::generate() in libzt.a(Identity.cpp.o)
      ZeroTier::Identity::locallyValidate() const in libzt.a(Identity.cpp.o)
      ZeroTier::Multicaster::send(void*, long long, ZeroTier::SharedPtr<ZeroTier::Network> const&, ZeroTier::Address const&, ZeroTier::MulticastGroup const&, ZeroTier::MAC const&, unsigned int, void const*, unsigned int) in libzt.a(Multicaster.cpp.o)
      ZeroTier::CertificateOfMembership::toString() const in libzt.a(CertificateOfMembership.cpp.o)
      ZeroTier::CertificateOfMembership::fromString(char const*) in libzt.a(CertificateOfMembership.cpp.o)
  "operator delete(void*)", referenced from:
      ZeroTier::init_subsystems() in libzt.a(Controls.cpp.o)
      _zts_id_new in libzt.a(Controls.cpp.o)
      __runNodeService in libzt.a(Controls.cpp.o)
      _zts_node_free in libzt.a(Controls.cpp.o)
      ZeroTier::Identity::~Identity() in libzt.a(Controls.cpp.o)
      _zts_util_sign_root_set in libzt.a(Utilities.cpp.o)
      std::__1::vector<ZeroTier::InetAddress, std::__1::allocator<ZeroTier::InetAddress> >::push_back(ZeroTier::InetAddress&&) in libzt.a(Utilities.cpp.o)
      ...
  "operator new[](unsigned long)", referenced from:
      ZeroTier::Identity::generate() in libzt.a(Identity.cpp.o)
      ZeroTier::Identity::locallyValidate() const in libzt.a(Identity.cpp.o)
      ZeroTier::Multicaster::send(void*, long long, ZeroTier::SharedPtr<ZeroTier::Network> const&, ZeroTier::Address const&, ZeroTier::MulticastGroup const&, ZeroTier::MAC const&, unsigned int, void const*, unsigned int) in libzt.a(Multicaster.cpp.o)
      ZeroTier::CertificateOfMembership::toString() const in libzt.a(CertificateOfMembership.cpp.o)
      ZeroTier::CertificateOfMembership::fromString(char const*) in libzt.a(CertificateOfMembership.cpp.o)
  "operator new(unsigned long)", referenced from:
      ZeroTier::init_subsystems() in libzt.a(Controls.cpp.o)
      _zts_id_new in libzt.a(Controls.cpp.o)
      _zts_util_sign_root_set in libzt.a(Utilities.cpp.o)
      std::__1::enable_if<(__is_cpp17_forward_iterator<ZeroTier::World::Root*>::value) && (is_constructible<ZeroTier::World::Root, std::__1::iterator_traits<ZeroTier::World::Root*>::reference>::value), void>::type std::__1::vector<ZeroTier::World::Root, std::__1::allocator<ZeroTier::World::Root> >::assign<ZeroTier::World::Root*>(ZeroTier::World::Root*, ZeroTier::World::Root*) in libzt.a(Utilities.cpp.o)
      std::__1::enable_if<__is_cpp17_forward_iterator<ZeroTier::World::Root*>::value, void>::type std::__1::vector<ZeroTier::World::Root, std::__1::allocator<ZeroTier::World::Root> >::__construct_at_end<ZeroTier::World::Root*>(ZeroTier::World::Root*, ZeroTier::World::Root*, unsigned long) in libzt.a(Utilities.cpp.o)
      std::__1::vector<ZeroTier::World::Root, std::__1::allocator<ZeroTier::World::Root> >::__vallocate(unsigned long) in libzt.a(Utilities.cpp.o)
      std::__1::vector<ZeroTier::InetAddress, std::__1::allocator<ZeroTier::InetAddress> >::__vallocate(unsigned long) in libzt.a(Utilities.cpp.o)
      ...
  "___cxa_allocate_exception", referenced from:
      void ZeroTier::World::serialize<8480u>(ZeroTier::Buffer<8480u>&, bool) const in libzt.a(Utilities.cpp.o)
      unsigned int ZeroTier::World::deserialize<8480u>(ZeroTier::Buffer<8480u> const&, unsigned int) in libzt.a(Utilities.cpp.o)
      ZeroTier::Identity::Identity(char const*) in libzt.a(Utilities.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(Utilities.cpp.o)
      void ZeroTier::Identity::serialize<8480u>(ZeroTier::Buffer<8480u>&, bool) const in libzt.a(Utilities.cpp.o)
      void ZeroTier::InetAddress::serialize<8480u>(ZeroTier::Buffer<8480u>&) const in libzt.a(Utilities.cpp.o)
      ZeroTier::Buffer<8480u>::operator[](unsigned int) const in libzt.a(Utilities.cpp.o)
      ...
  "___cxa_begin_catch", referenced from:
      __runNodeService in libzt.a(Controls.cpp.o)
      ___clang_call_terminate in libzt.a(Controls.cpp.o)
      ___clang_call_terminate in libzt.a(Utilities.cpp.o)
      ___clang_call_terminate in libzt.a(NodeService.cpp.o)
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      ZeroTier::Phy<ZeroTier::NodeService*>::poll(unsigned long) in libzt.a(NodeService.cpp.o)
      ZeroTier::Phy<ZeroTier::NodeService*>::udpBind(sockaddr const*, void*, int) in libzt.a(NodeService.cpp.o)
      ...
  "___cxa_call_unexpected", referenced from:
      ZeroTier::VirtualTap::threadMain() in libzt.a(VirtualTap.cpp.o)
      ZeroTier::OSUtils::redirectUnixOutputs(char const*, char const*) in libzt.a(OSUtils.cpp.o)
      ZeroTier::PortMapperImpl::threadMain() in libzt.a(PortMapper.cpp.o)
  "___cxa_end_catch", referenced from:
      __runNodeService in libzt.a(Controls.cpp.o)
      ZeroTier::NodeService::run() in libzt.a(NodeService.cpp.o)
      ZeroTier::Phy<ZeroTier::NodeService*>::poll(unsigned long) in libzt.a(NodeService.cpp.o)
      ZeroTier::Phy<ZeroTier::NodeService*>::udpBind(sockaddr const*, void*, int) in libzt.a(NodeService.cpp.o)
      ZeroTier::Phy<ZeroTier::NodeService*>::tcpListen(sockaddr const*, void*) in libzt.a(NodeService.cpp.o)
      ZeroTier::Node::Node(void*, void*, ZT_Node_Callbacks const*, long long) in libzt.a(Node.cpp.o)
      ZeroTier::Node::processBackgroundTasks(void*, long long, long long volatile*) in libzt.a(Node.cpp.o)
      ...
  "___cxa_free_exception", referenced from:
      std::__1::__throw_length_error(char const*) in libzt.a(Utilities.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(NodeService.cpp.o)
      ZeroTier::Phy<ZeroTier::NodeService*>::Phy(ZeroTier::NodeService*, bool, bool) in libzt.a(NodeService.cpp.o)
      ZeroTier::Thread ZeroTier::Thread::start<ZeroTier::VirtualTap>(ZeroTier::VirtualTap*) in libzt.a(VirtualTap.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::Phy<ZeroTier::VirtualTap*>::Phy(ZeroTier::VirtualTap*, bool, bool) in libzt.a(VirtualTap.cpp.o)
      ZeroTier::OSUtils::ztsnprintf(char*, unsigned int, char const*, ...) in libzt.a(OSUtils.cpp.o)
      ...
  "___cxa_guard_acquire", referenced from:
      ZeroTier::Utils::getSecureRandom(void*, unsigned int) in libzt.a(Utils.cpp.o)
      ZeroTier::NetworkConfig::fromDictionary(ZeroTier::Dictionary<419456u> const&) in libzt.a(NetworkConfig.cpp.o)
  "___cxa_guard_release", referenced from:
      ZeroTier::Utils::getSecureRandom(void*, unsigned int) in libzt.a(Utils.cpp.o)
      ZeroTier::NetworkConfig::fromDictionary(ZeroTier::Dictionary<419456u> const&) in libzt.a(NetworkConfig.cpp.o)
  "___cxa_rethrow", referenced from:
      ZeroTier::Node::Node(void*, void*, ZT_Node_Callbacks const*, long long) in libzt.a(Node.cpp.o)
      ZeroTier::Node::ncSendConfig(unsigned long long, unsigned long long, ZeroTier::Address const&, ZeroTier::NetworkConfig const&, bool) in libzt.a(Node.cpp.o)
      ZeroTier::NetworkConfig::toDictionary(ZeroTier::Dictionary<419456u>&, bool) const in libzt.a(NetworkConfig.cpp.o)
      ZeroTier::CertificateOfMembership::toString() const in libzt.a(CertificateOfMembership.cpp.o)
  "___cxa_throw", referenced from:
      void ZeroTier::World::serialize<8480u>(ZeroTier::Buffer<8480u>&, bool) const in libzt.a(Utilities.cpp.o)
      unsigned int ZeroTier::World::deserialize<8480u>(ZeroTier::Buffer<8480u> const&, unsigned int) in libzt.a(Utilities.cpp.o)
      ZeroTier::Identity::Identity(char const*) in libzt.a(Utilities.cpp.o)
      std::__1::__throw_length_error(char const*) in libzt.a(Utilities.cpp.o)
      void ZeroTier::Identity::serialize<8480u>(ZeroTier::Buffer<8480u>&, bool) const in libzt.a(Utilities.cpp.o)
      void ZeroTier::InetAddress::serialize<8480u>(ZeroTier::Buffer<8480u>&) const in libzt.a(Utilities.cpp.o)
      ZeroTier::Buffer<8480u>::operator[](unsigned int) const in libzt.a(Utilities.cpp.o)
      ...
  "___gxx_personality_v0", referenced from:
      ZeroTier::init_subsystems() in libzt.a(Controls.cpp.o)
      _zts_init_from_storage in libzt.a(Controls.cpp.o)
      _zts_init_from_memory in libzt.a(Controls.cpp.o)
      _zts_init_set_event_handler in libzt.a(Controls.cpp.o)
      _zts_init_blacklist_if in libzt.a(Controls.cpp.o)
      _zts_init_set_roots in libzt.a(Controls.cpp.o)
      _zts_init_set_port in libzt.a(Controls.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)

hope it helps

I’ve tried these steps on both macOS and my ubuntu VM without error. I’m not sure what’s happening on your system. I’ll try to think about this.

Also, may I ask what you mean by multipass ?

Hi Joseph,

Multipass is a sub system that you can install onto Mac and Windows by ubuntu. thanks for your assistance.

Hi Joseph, maybe I am doing a step wrong myside

  1. Git clone the repo
  2. change into the libzt directory
  3. Run ./build.sh host “release” or for mac ./build.sh host “release”
    4.run git submodule update --init
  4. then I change into the ~/libzt/examples/c and run gcc pingable-node.c -o pingable-node

which leads me to the error as stated previously, please let me know if I am doing something wrong?

******** Correction One** note I noticed, my linux version creates a dist directory whereas the mac version doesnt? (apologies I ran the build.sh script a second time and it actually created my release build on the mac.**

Good morning.

You have two main options:

  • A) Clone the repo and compile from source (best for experimentation, does not install)
  • B) Install on system via homebrew

Option (A):

git submodule update --init

This is the first command you must run in the new repo. Without its submodules there’s little to build. The build instructions show this as the first step.

Now, if you use the command ./build.sh host "release" that will build the libraries and examples and place them in the dist tree. The header file still remains in libzt/include/.

Crucially: This does not install libzt on your system.

If you want to build an executable like pingable-node you need to pass those two locations to your compiler/linker like so:

clang pingable-node.c -o pn path/to/where/library/is/libzt.a -Ipath/to/where/libzt/header/is -lpthread

Option (B):

Install the library and headers into system path:

brew install zerotier/tap/libzt

If you install this way, this is all you need to do, follow brews instructions if it says you need to link paths:

clang pingable-node.c -o pingable-node -lzt

If that doesn’t work, try providing the paths (will be different on your system):

clang pingable-node.c -o pn /home/linuxbrew/.linuxbrew/Cellar/libzt/1.4.1/lib/libzt.a -I/home/linuxbrew/.linuxbrew/Cellar/libzt/1.4.1/include -lpthread

To make this a little more concrete. This is what I did on my machine:

./build.sh host "debug"
libzt/dist/macos-x64-host-debug
├── bin
│   ├── adhoc
│   ├── callbackapi
│   ├── client
│   ├── customroots
│   ├── nonblockingclient
│   ├── nonblockingserver
│   ├── nostorage
│   ├── pingable-node
│   ├── server
│   └── statistics
└── lib
    ├── libzt.a
    └── libzt.dylib

As you can see, it already built the examples, but if you want to tweak them and build them yourself:

cd examples/c
clang pingable-node.c -o pingable-node -I../../include -L../../dist/macos-x64-host-release/lib -lzt

That’s all

Hi Joseph, thanks for the update and the help, I have rebuilt my dev environment as I think I was having some issues with libraries from my other projects. I am now goin to approach this vanilla from your input. I will update and let you know.

Update.

Step One after cloning the repo into my ~/projects/libzt folder
git submodule update --init
Submodule ‘ext/ZeroTierOne’ (https://github.com/zerotier/ZeroTierOne.git) registered for path ‘ext/ZeroTierOne’
Submodule ‘ext/lwip’ (https://github.com/joseph-henry/lwip.git) registered for path ‘ext/lwip’
Submodule ‘ext/lwip-contrib’ (https://github.com/joseph-henry/lwip-contrib.git) registered for path ‘ext/lwip-contrib’
Cloning into ‘/root/projects/libzt/ext/ZeroTierOne’…
Cloning into ‘/root/projects/libzt/ext/lwip-contrib’…
Cloning into ‘/root/projects/libzt/ext/lwip’…
Submodule path ‘ext/ZeroTierOne’: checked out ‘28df0c2e383ddb88d1afef2d0ac52046edd6cdbf’
Submodule path ‘ext/lwip’: checked out ‘32708c0a8b140efb545cc35101ee5fdeca6d6489’
Submodule path ‘ext/lwip-contrib’: checked out ‘4fd612c9c72dfcd1db6618bd59c1a17d9f5b55f8’

so far so good. When i run the ./build.sh host "release"
I get the following
./build.sh host “release”
– The C compiler identification is GNU 8.3.0
– The CXX compiler identification is GNU 8.3.0
– Check for working C compiler: /usr/bin/cc
– Check for working C compiler: /usr/bin/cc – works
– Detecting C compiler ABI info
– Detecting C compiler ABI info - done
– Detecting C compile features
– Detecting C compile features - done
– Check for working CXX compiler: /usr/bin/c++
– Check for working CXX compiler: /usr/bin/c++ – works
– Detecting CXX compiler ABI info
– Detecting CXX compiler ABI info - done
– Detecting CXX compile features
– Detecting CXX compile features - done
– Looking for pthread.h
– Looking for pthread.h - found
– Looking for pthread_create
– Looking for pthread_create - not found
– Looking for pthread_create in pthreads
– Looking for pthread_create in pthreads - not found
– Looking for pthread_create in pthread
– Looking for pthread_create in pthread - found
– Found Threads: TRUE
– Configuring done
CMake Error at CMakeLists.txt:632 (add_library):
Error evaluating generator expression:

    $<TARGET_OBJECTS:zt_pic>

  Objects of target "zt_pic" referenced but is not an OBJECT library.


CMake Error at CMakeLists.txt:632 (add_library):
  No SOURCES given to target: zt-static


-- Build files have been written to: /root/projects/libzt/cache/linux-x64-host-release
make: *** No targets specified and no makefile found.  Stop.
cp: cannot stat '/root/projects/libzt/cache/linux-x64-host-release/lib/libzt.*': No such file or directory
cp: cannot stat '/root/projects/libzt/cache/linux-x64-host-release/bin/*': No such file or directory

 - Build cache  : /root/projects/libzt/cache/linux-x64-host-release
 - Build output : /root/projects/libzt/dist

4	/root/projects/libzt/dist/linux-x64-host-release/lib
4	/root/projects/libzt/dist/linux-x64-host-release/bin
12	/root/projects/libzt/dist/linux-x64-host-release

looks like I am missing something at the ./build.sh host it didnt build the tree as you showed??

dist
|-- linux-x64-host-debug
|   |-- bin
|   `-- lib
`-- linux-x64-host-release
    |-- bin
    `-- lib