Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Protobuf package linkage problems #17993

Open
1 task done
daviyan5 opened this issue Mar 19, 2025 · 5 comments
Open
1 task done

[question] Protobuf package linkage problems #17993

daviyan5 opened this issue Mar 19, 2025 · 5 comments
Assignees

Comments

@daviyan5
Copy link

What is your question?

Hello,

I'm trying to compile (and cross-compile) a simple program using conan and CMake that depends on the protobuf library.

However, a number of strange problems are appearing in both build configurations.

When I try to compile for my machine (x86 Ubuntu 22.04), the resulting executable can't find the reference to protobuf unless I move the *.so files to the rpath. I figured this wouldn't be necessary since I'm linking the executable using ${protobuf_LIBRARIES}.

However, the biggest problem is that, during cross-compilation, the following error appears:

undefined reference to symbol '_ZN4absl12lts_2024072212log_internal21CheckOpMessageBuilder7ForVar2Ev'
build-conan-jetson/3rdparty/full_deploy/host/abseil/20240722.0/Debug/armv8/lib/libabsl_log_internal_check_op.so.2407.0.0: error adding symbols: DSO missing from command line

I believe that this could be a bug in the protobuf package, since there are some issues about similar problems:

protocolbuffers/protobuf#15604
protocolbuffers/protobuf#12637

The problem is that the "solutions" indicated in these issues did not apply to my case, and I would like to know if I am doing something wrong with conan2.

Here are the profiles I'm using:

default:

[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux

jetson:

[settings]
arch=armv8
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
 
[buildenv]
CC=aarch64-linux-gnu-gcc
CXX=aarch64-linux-gnu-g++

And here are the project files:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(Example)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-g -Wall -Werror ${CMAKE_CXX_FLAGS}")
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)

find_package(Protobuf CONFIG REQUIRED)

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS simple.proto)
add_library(simple_proto SHARED ${PROTO_SRCS})
target_link_libraries(simple_proto ${protobuf_LIBRARIES})
target_include_directories(simple_proto PUBLIC ${protobuf_INCLUDE_DIRS})

install(TARGETS simple_proto DESTINATION lib)

add_executable(main main.cpp)
target_link_libraries(main PUBLIC simple_proto PRIVATE ${protobuf_LIBRARIES})
target_include_directories(main PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${protobuf_INCLUDE_DIRS})

file(GLOB PROTOBUF_OBJECTS
     ${protobuf_LIB_DIRS_DEBUG}/*.so
     ${protobuf_LIB_DIRS_DEBUG}/*.so.*)

file(GLOB ABSEIL_OBJECTS
     ${abseil_LIB_DIRS_DEBUG}/*.so
     ${abseil_LIB_DIRS_DEBUG}/*.so.*)

install(
  FILES
    ${PROTOBUF_OBJECTS} 
    ${ABSEIL_OBJECTS}
  DESTINATION lib)

install(TARGETS main DESTINATION bin)

I'm using the 'file' directive to move the .so objects to lib, and that's the only way I've been able to get the x86 build to work. Without it, the build won't throw any errors, but on runtime it will flag the inability to find the .so objects.

conanfile.txt:

[requires]
protobuf/5.27.0

[tool_requires]
protobuf/5.27.0

[generators]
CMakeDeps
CMakeToolchain

main.cpp:

#include <iostream>
#include <string>

#include "simple.pb.h"


int main()
{
    MyMessage message;
    message.set_name("Hello, world!");

    std::string serialized;
    message.SerializeToString(&serialized);
    
    MyMessage new_message;
    new_message.ParseFromString(serialized);
    std::cout << "Deserialized: " << new_message.name() << std::endl;

    return 0;

}

simple.proto:

syntax = "proto3";

message MyMessage {
    string name = 1;
}

Commands I'm using to compile the code:

x86:

rm -rf build-conan-x86_64
mkdir build-conan-x86_64 -p
conan install . --output-folder=build-conan-x86_64 \
                --profile:host=default --profile:build=default \
                --build=missing --settings=build_type=Debug -o *:shared=True \
                --deployer=full_deploy --deployer-folder=build-conan-x86_64/3rdparty
cd build-conan-x86_64
source conanbuild.sh 
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=stage
make install -j8

Cross-compilation (jetson):

rm -rf build-conan-jetson
mkdir build-conan-jetson -p
conan install . --output-folder=build-conan-jetson \
                --profile:host=jetson --profile:build=default \
                --build=missing --settings=build_type=Debug -o *:shared=True \
                --deployer=full_deploy --deployer-folder=build-conan-jetson/3rdparty
cd build-conan-jetson
source conanbuild.sh 
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=stage
make install -j8

Another important information: I've tested compiling both protobuf and abseil with shared=False in the cross-compilation case, and I believe it may have worked (at least the compilation did, but I don't know if the linkage was done correctly). I'll check later on the Jetson itself.

Thanks for the consideration.

Have you read the CONTRIBUTING guide?

  • I've read the CONTRIBUTING guide
@memsharded memsharded self-assigned this Mar 19, 2025
@memsharded
Copy link
Member

Hi @daviyan5

Thanks for your report.

I haven't fully checked your files yet, but some quick comments:

  • protobuf_LIBRARIES and other variables shouldn't be really used. Those are in general intended to be internal implementation variables, or at most legacy variables for legacy consumers. The recommended CMake way is to use targets, and Conan generate targets (they are printed in the CMake output when loaded), but are in the form of protobuf::protobuf or something like that.
  • This also applies for all variables, like protobuf_INCLUDE_DIRS
  • The problem with this is that you might be missing other information attached to the targets, like compile flags, necessary system libraries or transitive information.
  • CMakeLists.txt shouldn't hardcode something like set(CMAKE_CXX_STANDARD 17). This typically belongs to toolchain files, so it can be parameterized. The Conan toolchain will manage this automatically, but if the CMakeLists.txt hardcodes it, you could be defining -s compiler.cppstd=20, but your project will not use it because even if Conan defines it, your own set will overwrite and discard that value.

Then, I'd strongly also recommend the following:

  • Update your conanfile.txt to a conanfile.py
  • Add there a build() method with the necessary cmake.configure() + cmake.build()
  • Add also a layout() method with cmake_layout(self)

then, all your build code reduces to a simple conan build . -pr:h=jetson -pr:b=default, which helps a lot for reproducibility and convenience.

The deployers shouldn't be necessary at all for development, those are only intended for final deployment of applications outside Conan. You should be able to safely drop them for development.

Could you please give that a try and let us know (please update the files if you do)?

Reproducing exactly for the jetson might be a bit challenging, because it also depends on the jetson itself, the toolchain, etc. Maybe if it can be reproduced in some common available docker image with some standard cross-compiler to arm, that would help to reproduce it on our end.

Thanks!

@daviyan5
Copy link
Author

daviyan5 commented Mar 20, 2025

Thanks a lot for the quick answer.
However, I was unable to apply the recommendation of converting my build commands into a conanfile.py
This was my attempt:

from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout, CMakeToolchain


class ExampleConan(ConanFile):
    name="example"
    version="0.1"
    settings="os", "compiler", "build_type", "arch"
    options = {
        "shared": [True, False]
    }
    default_options = {
        "shared": True
    }
    generators = "CMakeDeps"

    requires = "protobuf/5.27.0"
    tool_requires = "protobuf/5.27.0"

    def generate(self):
        tc = CMakeToolchain(self)
        tc.variables["CMAKE_INSTALL_PREFIX"] = "stage"
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()
        cmake.install()

With the CMakeLists.txt changed to:

cmake_minimum_required(VERSION 3.15)
project(Example)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "-g -Wall -Werror ${CMAKE_CXX_FLAGS}")
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)

find_package(Protobuf CONFIG REQUIRED)

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS simple.proto)
add_library(simple_proto SHARED ${PROTO_SRCS})
target_link_libraries(simple_proto protobuf::protobuf)

install(TARGETS simple_proto DESTINATION lib)

add_executable(main main.cpp)
target_link_libraries(main PUBLIC simple_proto PRIVATE protobuf::protobuf)
target_include_directories(main PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

file(GLOB PROTOBUF_OBJECTS
     ${protobuf_LIB_DIRS_DEBUG}/*.so
     ${protobuf_LIB_DIRS_DEBUG}/*.so.*)

file(GLOB ABSEIL_OBJECTS
     ${abseil_LIB_DIRS_DEBUG}/*.so
     ${abseil_LIB_DIRS_DEBUG}/*.so.*)

install(
  FILES
    ${PROTOBUF_OBJECTS} 
    ${ABSEIL_OBJECTS}
  DESTINATION lib)

install(TARGETS main DESTINATION bin)

And then, I run it like this:

rm -rf build-conan-x86_64
mkdir build-conan-x86_64 -p
conan install . --output-folder=build-conan-x86_64 \
	-pr:h=default -pr:b=default \
	--settings=build_type=Debug -o *:shared=True \
	--deployer=full_deploy --deployer-folder=build-conan-x86_64/3rdparty
conan build . -of build-conan-x86_64 -pr:h=default -pr:b=default

However, besides the fact that the size of the commands didn't really get smaller or simpler (the options and settings configurations that I'm putting on the command are necessary for the project, that's why I did not change them), I now have build errors like:

CMake Error at /usr/share/cmake-3.22/Modules/CMakeTestCCompiler.cmake:69 (message):
  The C compiler

    "/usr/bin/aarch64-linux-gnu-gcc"

  is not able to compile a simple test program.

  It fails with the following output:
/usr/bin/aarch64-linux-gnu-gcc   -m64  -o CMakeFiles/cmTC_d74e7.dir/testCCompiler.c.o -c ${MY_PROJECT_FOLDER}/build-conan-x86_64/CMakeFiles/CMakeTmp/testCCompiler.c
aarch64-linux-gnu-gcc: error: unrecognized command-line option ‘-m64’

Which didn't happen with my original commands. For some reason, even when trying to run the native build, it's trying to compile the cross-compilation dependencies, and indicating some error related to non-existent flags. I really don't know what's going on, although I feel like I'm doing something very wrong. I didn't touch any other files besides conanfile.py and CMakeLists.txt

I'm testing the deployment itself, hence the need to use the deployer. And, as I mentioned, the link with protobuf doesn't seem to work if I don't move the .so files to rpath

Also, the compiler I'm using to cross compile is the aarch64-linux-gnu-gcc that comes on the Cuda Toolkit 12.6 for Cross-Compilation. Reproducing the jetson is indeed problematic, as I believe one would have to use qemu to emulate the armv8 architecture. There are docker images and tutorials on it, but it may be too much work for just checking binaries linkage. As I said previously, on the worst possible case the static compilation of the dependencies was enough to make both the cross-compilation and the execution on the jetson to work, so if I managed to just make the cross-compilation work with shared objects it would be very nice. For now, the error persists even after changing only the CMakeLists.txt and executing the build commands I wrote previously here (not the updated ones for the conanfile.py).

Thanks a lot and sorry for the trouble.

@daviyan5
Copy link
Author

Okay, the build error is of course related to CC and CXX being set on the shell environment to the cross-compiler. I don't know why it's happening now but wasn't before haha. Maybe related to the sourcing of conanbuild.sh?

@memsharded
Copy link
Member

This was my attempt:

there are still some missing things:

  • The layout() method with cmake_layout(self) call
  • cmake.install() shouldn't be called in build() method but in package() method
  • The tc.variables["CMAKE_INSTALL_PREFIX"] = "stage" also typically not necessary.
  • Then conan install . can be replaced very conveniently with conan build . -pr=profile avoiding things like the --output-folder.
  • Also the deployer shouldnt be necessary here for normal development

To have something that fully works, you can try this flow with the conan new template:

conan new cmake_lib -d name=mypkg -d version=0.1
conan build .

If you are passing arguments they should be passed to conan build . -o *:shared=True .. as well, as it does call conan install internally. It is not necessary to call conan install before conan build and if doing that with different arguments it would be incorrect.

I'm testing the deployment itself, hence the need to use the deployer. And, as I mentioned, the link with protobuf doesn't seem to work if I don't move the .so files to rpath

That seems a different issue, linking with protobuf shared is possible and tested, without having to do rpath manipulations and without deploying anything.

Thanks a lot and sorry for the trouble.

Not a trouble at all! We are really happy to help as much as possible :)

Debugging and solving these kind of issues that have that many moving pieces: external dependencies, both requires and tool-requires, cross-compilation for a special platform, using deployers, changing rpaths, etc, can be quite challenging. This is why it is important to reduce as much as possible the case, removing moving pieces not strictly necessary for reproduction and trying to provide reproduction tools like docker images or the like.

In this case, the issue about aarch64-linux-gnu-gcc -m64 could be that the current Conan integrations is adding a compiler flag for the architecture that this specific compiler, even if it looks like gcc, it doesn't accept this flag.

But it is not even clear in which package the build error is happening, if it is in your own build, in the build of one of the dependencies. If the build is one of the dependencies, then all your local conanfile.py and CMakeLists.txt are actually not necessary at all, and it should be possible to reproduce with something like:

conan install --requires=offending_pkg/version --build=offending_pkg* -pr=myprofile

And if the error is happening in your current package and not the dependencies, it is likely that it can be reproduced removing completely the dependencies, because it seems it is failing at the line project(Example), which is the one that does compilation of small tests projects (like /cmTC_d74e7.dir/testCCompiler.c.o) to define and setup the toolchain, but that means that happens even before find_package() or buiding anything of your project.

In general the smaller the problem and the more easily reproducible, the faster questions and issues are resolved, specially when there are limited resources and often support tickets are resolved in small time windows, so if the issue is complicated and require to allocate, lets say 2 consecutive hours for 1 reproduction, it is way more unlikely than if it could be done in 4 small chunks of 30 mins.

@daviyan5
Copy link
Author

daviyan5 commented Mar 26, 2025

Sorry for the delay in responding.

I changed conanfile.py to include cmake_layout and removed unnecessary options to make it easier to reproduce.

Now, I run the code with the following commands:

rm -rf build
conan build . -o *:shared=True -pr:h=default -pr:b=default
cmake --install build/Release --prefix stage/x86

And for the cross-compilation:

rm -rf build
conan build . -o *:shared=True -pr:h=jetson -pr:b=default --build=missing
cmake --install build/Release --prefix stage/aarch64

This works well, however, the linkage problems persist, and I hope it now be more evident and easy to reproduce:

~/Documents/test/stage/Release/x86$ ldd bin/main 
        linux-vdso.so.1 (0x00007ffdb99ac000)
        libsimple_proto.so => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libsimple_proto.so (0x000076cbc49d0000)
        libprotobuf.so.27.0.0 => not found
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x000076cbc4600000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x000076cbc499d000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000076cbc4200000)
        libprotobuf.so.27.0.0 => not found
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000076cbc48b4000)
        /lib64/ld-linux-x86-64.so.2 (0x000076cbc49dd000)

~/Documents/test/stage/Release/x86$ tree
.
├── bin
│   └── main
└── lib
    └── libsimple_proto.so

This is the output of ldd from the x86 compilation.
If I, again, uncomment the # ----- ***** ------ section in the CMakeLists.txt to move the .so's (ABSEIL_OBJECTS and PROTOBUF_OBJECTS) to lib, it works:

~/Documents/test/stage/Release/x86$ ldd bin/main 
        linux-vdso.so.1 (0x00007ffefebf9000)
        libsimple_proto.so => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libsimple_proto.so (0x00007ae31b189000)
        libprotobuf.so.27.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libprotobuf.so.27.0.0 (0x00007ae31ae00000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ae31aa00000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ae31b156000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ae31a600000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ae31b14f000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007ae31b133000)
        libabsl_log_internal_check_op.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_check_op.so.2501.0.0 (0x00007ae31b12b000)
        libabsl_die_if_null.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_die_if_null.so.2501.0.0 (0x00007ae31b126000)
        libabsl_log_internal_conditions.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_conditions.so.2501.0.0 (0x00007ae31b121000)
        libabsl_log_internal_message.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_message.so.2501.0.0 (0x00007ae31b111000)
        libabsl_log_internal_nullguard.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_nullguard.so.2501.0.0 (0x00007ae31b10c000)
        libabsl_raw_hash_set.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_raw_hash_set.so.2501.0.0 (0x00007ae31b106000)
        libabsl_hash.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_hash.so.2501.0.0 (0x00007ae31b101000)
        libabsl_statusor.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_statusor.so.2501.0.0 (0x00007ae31b0fb000)
        libabsl_status.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_status.so.2501.0.0 (0x00007ae31b0ed000)
        libabsl_cord.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_cord.so.2501.0.0 (0x00007ae31addf000)
        libabsl_cordz_info.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_cordz_info.so.2501.0.0 (0x00007ae31b0e6000)
        libabsl_cord_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_cord_internal.so.2501.0.0 (0x00007ae31b0d3000)
        libabsl_synchronization.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_synchronization.so.2501.0.0 (0x00007ae31adce000)
        libabsl_time.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_time.so.2501.0.0 (0x00007ae31adb7000)
        libabsl_time_zone.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_time_zone.so.2501.0.0 (0x00007ae31ad97000)
        libabsl_str_format_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_str_format_internal.so.2501.0.0 (0x00007ae31ad7c000)
        libabsl_strings.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_strings.so.2501.0.0 (0x00007ae31ad5a000)
        libabsl_spinlock_wait.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_spinlock_wait.so.2501.0.0 (0x00007ae31ad55000)
        libabsl_throw_delegate.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_throw_delegate.so.2501.0.0 (0x00007ae31ad4e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ae31b196000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ae31ac67000)
        libabsl_leak_check.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_leak_check.so.2501.0.0 (0x00007ae31ac62000)
        libabsl_base.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_base.so.2501.0.0 (0x00007ae31ac5c000)
        libabsl_examine_stack.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_examine_stack.so.2501.0.0 (0x00007ae31ac57000)
        libabsl_log_internal_format.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_format.so.2501.0.0 (0x00007ae31ac52000)
        libabsl_log_internal_structured_proto.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_structured_proto.so.2501.0.0 (0x00007ae31ac4d000)
        libabsl_strerror.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_strerror.so.2501.0.0 (0x00007ae31ac48000)
        libabsl_log_internal_proto.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_proto.so.2501.0.0 (0x00007ae31ac43000)
        libabsl_log_internal_log_sink_set.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_log_sink_set.so.2501.0.0 (0x00007ae31ac3d000)
        libabsl_log_internal_globals.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_internal_globals.so.2501.0.0 (0x00007ae31ac36000)
        libabsl_log_globals.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_globals.so.2501.0.0 (0x00007ae31ac30000)
        libabsl_raw_logging_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_raw_logging_internal.so.2501.0.0 (0x00007ae31a9fb000)
        libabsl_city.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_city.so.2501.0.0 (0x00007ae31a9f6000)
        libabsl_low_level_hash.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_low_level_hash.so.2501.0.0 (0x00007ae31a9f1000)
        libabsl_crc_cord_state.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_crc_cord_state.so.2501.0.0 (0x00007ae31a9e9000)
        libabsl_cordz_functions.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_cordz_functions.so.2501.0.0 (0x00007ae31a9e4000)
        libabsl_cordz_handle.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_cordz_handle.so.2501.0.0 (0x00007ae31a9de000)
        libabsl_stacktrace.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_stacktrace.so.2501.0.0 (0x00007ae31a9d9000)
        libabsl_kernel_timeout_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_kernel_timeout_internal.so.2501.0.0 (0x00007ae31a9d4000)
        libabsl_tracing_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_tracing_internal.so.2501.0.0 (0x00007ae31a9cf000)
        libabsl_malloc_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_malloc_internal.so.2501.0.0 (0x00007ae31a9c9000)
        libabsl_int128.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_int128.so.2501.0.0 (0x00007ae31a9c2000)
        libabsl_strings_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_strings_internal.so.2501.0.0 (0x00007ae31a9bc000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ae31a9b7000)
        libabsl_symbolize.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_symbolize.so.2501.0.0 (0x00007ae31a9ac000)
        libabsl_log_sink.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_log_sink.so.2501.0.0 (0x00007ae31a9a7000)
        libabsl_crc32c.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_crc32c.so.2501.0.0 (0x00007ae31a9a1000)
        libabsl_exponential_biased.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_exponential_biased.so.2501.0.0 (0x00007ae31a99c000)
        libabsl_debugging_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_debugging_internal.so.2501.0.0 (0x00007ae31a993000)
        libabsl_demangle_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_demangle_internal.so.2501.0.0 (0x00007ae31a981000)
        libabsl_crc_internal.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_crc_internal.so.2501.0.0 (0x00007ae31a97a000)
        libabsl_demangle_rust.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_demangle_rust.so.2501.0.0 (0x00007ae31a973000)
        libabsl_decode_rust_punycode.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_decode_rust_punycode.so.2501.0.0 (0x00007ae31a96c000)
        libabsl_utf8_for_code_point.so.2501.0.0 => /home/dybranda/Documents/test/stage/Release/x86/bin/../lib/libabsl_utf8_for_code_point.so.2501.0.0 (0x00007ae31a967000

~/Documents/test/stage/Release/x86$ tree
.
├── bin
│   └── main
└── lib
    ├── libabsl_bad_any_cast_impl.so -> libabsl_bad_any_cast_impl.so.2501.0.0
    ├── libabsl_bad_any_cast_impl.so.2501.0.0
    ├── libabsl_bad_optional_access.so -> libabsl_bad_optional_access.so.2501.0.0
    ├── libabsl_bad_optional_access.so.2501.0.0
    ├── libabsl_bad_variant_access.so -> libabsl_bad_variant_access.so.2501.0.0
    ├── libabsl_bad_variant_access.so.2501.0.0
    ├── libabsl_base.so -> libabsl_base.so.2501.0.0
    ├── libabsl_base.so.2501.0.0
    ├── libabsl_city.so -> libabsl_city.so.2501.0.0
    ├── libabsl_city.so.2501.0.0
    ├── libabsl_civil_time.so -> libabsl_civil_time.so.2501.0.0
    ├── libabsl_civil_time.so.2501.0.0
    ├── libabsl_cord_internal.so -> libabsl_cord_internal.so.2501.0.0
    ├── libabsl_cord_internal.so.2501.0.0
    ├── libabsl_cord.so -> libabsl_cord.so.2501.0.0
    ├── libabsl_cord.so.2501.0.0
    ├── libabsl_cordz_functions.so -> libabsl_cordz_functions.so.2501.0.0
    ├── libabsl_cordz_functions.so.2501.0.0
    ├── libabsl_cordz_handle.so -> libabsl_cordz_handle.so.2501.0.0
    ├── libabsl_cordz_handle.so.2501.0.0
    ├── libabsl_cordz_info.so -> libabsl_cordz_info.so.2501.0.0
    ├── libabsl_cordz_info.so.2501.0.0
    ├── libabsl_cordz_sample_token.so -> libabsl_cordz_sample_token.so.2501.0.0
    ├── libabsl_cordz_sample_token.so.2501.0.0
    ├── libabsl_crc32c.so -> libabsl_crc32c.so.2501.0.0
    ├── libabsl_crc32c.so.2501.0.0
    ├── libabsl_crc_cord_state.so -> libabsl_crc_cord_state.so.2501.0.0
    ├── libabsl_crc_cord_state.so.2501.0.0
    ├── libabsl_crc_cpu_detect.so -> libabsl_crc_cpu_detect.so.2501.0.0
    ├── libabsl_crc_cpu_detect.so.2501.0.0
    ├── libabsl_crc_internal.so -> libabsl_crc_internal.so.2501.0.0
    ├── libabsl_crc_internal.so.2501.0.0
    ├── libabsl_debugging_internal.so -> libabsl_debugging_internal.so.2501.0.0
    ├── libabsl_debugging_internal.so.2501.0.0
    ├── libabsl_decode_rust_punycode.so -> libabsl_decode_rust_punycode.so.2501.0.0
    ├── libabsl_decode_rust_punycode.so.2501.0.0
    ├── libabsl_demangle_internal.so -> libabsl_demangle_internal.so.2501.0.0
    ├── libabsl_demangle_internal.so.2501.0.0
    ├── libabsl_demangle_rust.so -> libabsl_demangle_rust.so.2501.0.0
    ├── libabsl_demangle_rust.so.2501.0.0
    ├── libabsl_die_if_null.so -> libabsl_die_if_null.so.2501.0.0
    ├── libabsl_die_if_null.so.2501.0.0
    ├── libabsl_examine_stack.so -> libabsl_examine_stack.so.2501.0.0
    ├── libabsl_examine_stack.so.2501.0.0
    ├── libabsl_exponential_biased.so -> libabsl_exponential_biased.so.2501.0.0
    ├── libabsl_exponential_biased.so.2501.0.0
    ├── libabsl_failure_signal_handler.so -> libabsl_failure_signal_handler.so.2501.0.0
    ├── libabsl_failure_signal_handler.so.2501.0.0
    ├── libabsl_flags_commandlineflag_internal.so -> libabsl_flags_commandlineflag_internal.so.2501.0.0
    ├── libabsl_flags_commandlineflag_internal.so.2501.0.0
    ├── libabsl_flags_commandlineflag.so -> libabsl_flags_commandlineflag.so.2501.0.0
    ├── libabsl_flags_commandlineflag.so.2501.0.0
    ├── libabsl_flags_config.so -> libabsl_flags_config.so.2501.0.0
    ├── libabsl_flags_config.so.2501.0.0
    ├── libabsl_flags_internal.so -> libabsl_flags_internal.so.2501.0.0
    ├── libabsl_flags_internal.so.2501.0.0
    ├── libabsl_flags_marshalling.so -> libabsl_flags_marshalling.so.2501.0.0
    ├── libabsl_flags_marshalling.so.2501.0.0
    ├── libabsl_flags_parse.so -> libabsl_flags_parse.so.2501.0.0
    ├── libabsl_flags_parse.so.2501.0.0
    ├── libabsl_flags_private_handle_accessor.so -> libabsl_flags_private_handle_accessor.so.2501.0.0
    ├── libabsl_flags_private_handle_accessor.so.2501.0.0
    ├── libabsl_flags_program_name.so -> libabsl_flags_program_name.so.2501.0.0
    ├── libabsl_flags_program_name.so.2501.0.0
    ├── libabsl_flags_reflection.so -> libabsl_flags_reflection.so.2501.0.0
    ├── libabsl_flags_reflection.so.2501.0.0
    ├── libabsl_flags_usage_internal.so -> libabsl_flags_usage_internal.so.2501.0.0
    ├── libabsl_flags_usage_internal.so.2501.0.0
    ├── libabsl_flags_usage.so -> libabsl_flags_usage.so.2501.0.0
    ├── libabsl_flags_usage.so.2501.0.0
    ├── libabsl_graphcycles_internal.so -> libabsl_graphcycles_internal.so.2501.0.0
    ├── libabsl_graphcycles_internal.so.2501.0.0
    ├── libabsl_hash.so -> libabsl_hash.so.2501.0.0
    ├── libabsl_hash.so.2501.0.0
    ├── libabsl_hashtablez_sampler.so -> libabsl_hashtablez_sampler.so.2501.0.0
    ├── libabsl_hashtablez_sampler.so.2501.0.0
    ├── libabsl_int128.so -> libabsl_int128.so.2501.0.0
    ├── libabsl_int128.so.2501.0.0
    ├── libabsl_kernel_timeout_internal.so -> libabsl_kernel_timeout_internal.so.2501.0.0
    ├── libabsl_kernel_timeout_internal.so.2501.0.0
    ├── libabsl_leak_check.so -> libabsl_leak_check.so.2501.0.0
    ├── libabsl_leak_check.so.2501.0.0
    ├── libabsl_log_entry.so -> libabsl_log_entry.so.2501.0.0
    ├── libabsl_log_entry.so.2501.0.0
    ├── libabsl_log_flags.so -> libabsl_log_flags.so.2501.0.0
    ├── libabsl_log_flags.so.2501.0.0
    ├── libabsl_log_globals.so -> libabsl_log_globals.so.2501.0.0
    ├── libabsl_log_globals.so.2501.0.0
    ├── libabsl_log_initialize.so -> libabsl_log_initialize.so.2501.0.0
    ├── libabsl_log_initialize.so.2501.0.0
    ├── libabsl_log_internal_check_op.so -> libabsl_log_internal_check_op.so.2501.0.0
    ├── libabsl_log_internal_check_op.so.2501.0.0
    ├── libabsl_log_internal_conditions.so -> libabsl_log_internal_conditions.so.2501.0.0
    ├── libabsl_log_internal_conditions.so.2501.0.0
    ├── libabsl_log_internal_fnmatch.so -> libabsl_log_internal_fnmatch.so.2501.0.0
    ├── libabsl_log_internal_fnmatch.so.2501.0.0
    ├── libabsl_log_internal_format.so -> libabsl_log_internal_format.so.2501.0.0
    ├── libabsl_log_internal_format.so.2501.0.0
    ├── libabsl_log_internal_globals.so -> libabsl_log_internal_globals.so.2501.0.0
    ├── libabsl_log_internal_globals.so.2501.0.0
    ├── libabsl_log_internal_log_sink_set.so -> libabsl_log_internal_log_sink_set.so.2501.0.0
    ├── libabsl_log_internal_log_sink_set.so.2501.0.0
    ├── libabsl_log_internal_message.so -> libabsl_log_internal_message.so.2501.0.0
    ├── libabsl_log_internal_message.so.2501.0.0
    ├── libabsl_log_internal_nullguard.so -> libabsl_log_internal_nullguard.so.2501.0.0
    ├── libabsl_log_internal_nullguard.so.2501.0.0
    ├── libabsl_log_internal_proto.so -> libabsl_log_internal_proto.so.2501.0.0
    ├── libabsl_log_internal_proto.so.2501.0.0
    ├── libabsl_log_internal_structured_proto.so -> libabsl_log_internal_structured_proto.so.2501.0.0
    ├── libabsl_log_internal_structured_proto.so.2501.0.0
    ├── libabsl_log_severity.so -> libabsl_log_severity.so.2501.0.0
    ├── libabsl_log_severity.so.2501.0.0
    ├── libabsl_log_sink.so -> libabsl_log_sink.so.2501.0.0
    ├── libabsl_log_sink.so.2501.0.0
    ├── libabsl_low_level_hash.so -> libabsl_low_level_hash.so.2501.0.0
    ├── libabsl_low_level_hash.so.2501.0.0
    ├── libabsl_malloc_internal.so -> libabsl_malloc_internal.so.2501.0.0
    ├── libabsl_malloc_internal.so.2501.0.0
    ├── libabsl_periodic_sampler.so -> libabsl_periodic_sampler.so.2501.0.0
    ├── libabsl_periodic_sampler.so.2501.0.0
    ├── libabsl_poison.so -> libabsl_poison.so.2501.0.0
    ├── libabsl_poison.so.2501.0.0
    ├── libabsl_random_distributions.so -> libabsl_random_distributions.so.2501.0.0
    ├── libabsl_random_distributions.so.2501.0.0
    ├── libabsl_random_internal_distribution_test_util.so -> libabsl_random_internal_distribution_test_util.so.2501.0.0
    ├── libabsl_random_internal_distribution_test_util.so.2501.0.0
    ├── libabsl_random_internal_platform.so -> libabsl_random_internal_platform.so.2501.0.0
    ├── libabsl_random_internal_platform.so.2501.0.0
    ├── libabsl_random_internal_pool_urbg.so -> libabsl_random_internal_pool_urbg.so.2501.0.0
    ├── libabsl_random_internal_pool_urbg.so.2501.0.0
    ├── libabsl_random_internal_randen_hwaes_impl.so -> libabsl_random_internal_randen_hwaes_impl.so.2501.0.0
    ├── libabsl_random_internal_randen_hwaes_impl.so.2501.0.0
    ├── libabsl_random_internal_randen_hwaes.so -> libabsl_random_internal_randen_hwaes.so.2501.0.0
    ├── libabsl_random_internal_randen_hwaes.so.2501.0.0
    ├── libabsl_random_internal_randen_slow.so -> libabsl_random_internal_randen_slow.so.2501.0.0
    ├── libabsl_random_internal_randen_slow.so.2501.0.0
    ├── libabsl_random_internal_randen.so -> libabsl_random_internal_randen.so.2501.0.0
    ├── libabsl_random_internal_randen.so.2501.0.0
    ├── libabsl_random_internal_seed_material.so -> libabsl_random_internal_seed_material.so.2501.0.0
    ├── libabsl_random_internal_seed_material.so.2501.0.0
    ├── libabsl_random_seed_gen_exception.so -> libabsl_random_seed_gen_exception.so.2501.0.0
    ├── libabsl_random_seed_gen_exception.so.2501.0.0
    ├── libabsl_random_seed_sequences.so -> libabsl_random_seed_sequences.so.2501.0.0
    ├── libabsl_random_seed_sequences.so.2501.0.0
    ├── libabsl_raw_hash_set.so -> libabsl_raw_hash_set.so.2501.0.0
    ├── libabsl_raw_hash_set.so.2501.0.0
    ├── libabsl_raw_logging_internal.so -> libabsl_raw_logging_internal.so.2501.0.0
    ├── libabsl_raw_logging_internal.so.2501.0.0
    ├── libabsl_scoped_set_env.so -> libabsl_scoped_set_env.so.2501.0.0
    ├── libabsl_scoped_set_env.so.2501.0.0
    ├── libabsl_spinlock_wait.so -> libabsl_spinlock_wait.so.2501.0.0
    ├── libabsl_spinlock_wait.so.2501.0.0
    ├── libabsl_stacktrace.so -> libabsl_stacktrace.so.2501.0.0
    ├── libabsl_stacktrace.so.2501.0.0
    ├── libabsl_statusor.so -> libabsl_statusor.so.2501.0.0
    ├── libabsl_statusor.so.2501.0.0
    ├── libabsl_status.so -> libabsl_status.so.2501.0.0
    ├── libabsl_status.so.2501.0.0
    ├── libabsl_strerror.so -> libabsl_strerror.so.2501.0.0
    ├── libabsl_strerror.so.2501.0.0
    ├── libabsl_str_format_internal.so -> libabsl_str_format_internal.so.2501.0.0
    ├── libabsl_str_format_internal.so.2501.0.0
    ├── libabsl_strings_internal.so -> libabsl_strings_internal.so.2501.0.0
    ├── libabsl_strings_internal.so.2501.0.0
    ├── libabsl_strings.so -> libabsl_strings.so.2501.0.0
    ├── libabsl_strings.so.2501.0.0
    ├── libabsl_string_view.so -> libabsl_string_view.so.2501.0.0
    ├── libabsl_string_view.so.2501.0.0
    ├── libabsl_symbolize.so -> libabsl_symbolize.so.2501.0.0
    ├── libabsl_symbolize.so.2501.0.0
    ├── libabsl_synchronization.so -> libabsl_synchronization.so.2501.0.0
    ├── libabsl_synchronization.so.2501.0.0
    ├── libabsl_throw_delegate.so -> libabsl_throw_delegate.so.2501.0.0
    ├── libabsl_throw_delegate.so.2501.0.0
    ├── libabsl_time.so -> libabsl_time.so.2501.0.0
    ├── libabsl_time.so.2501.0.0
    ├── libabsl_time_zone.so -> libabsl_time_zone.so.2501.0.0
    ├── libabsl_time_zone.so.2501.0.0
    ├── libabsl_tracing_internal.so -> libabsl_tracing_internal.so.2501.0.0
    ├── libabsl_tracing_internal.so.2501.0.0
    ├── libabsl_utf8_for_code_point.so -> libabsl_utf8_for_code_point.so.2501.0.0
    ├── libabsl_utf8_for_code_point.so.2501.0.0
    ├── libabsl_vlog_config_internal.so -> libabsl_vlog_config_internal.so.2501.0.0
    ├── libabsl_vlog_config_internal.so.2501.0.0
    ├── libprotobuf.so -> libprotobuf.so.27.0.0
    ├── libprotobuf.so.27.0.0
    ├── libprotoc.so -> libprotoc.so.27.0.0
    ├── libprotoc.so.27.0.0
    └── libsimple_proto.so

The good news is that it works on the Jetson as well and, since I was already going to need to move the 3rdparty objects into the Jetson, the above solution is convenient enough (and probably the only one).

So I wonder why the undefined reference error was happening. I don't know which part of the reorganization fixed this problem, but thanks a lot for the help!

Here are all the files used in the project

CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
project(Example)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "-g -Wall -Werror ${CMAKE_CXX_FLAGS}")
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)

find_package(Protobuf CONFIG REQUIRED)

protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS simple.proto)
add_library(simple_proto SHARED ${PROTO_SRCS})
target_link_libraries(simple_proto protobuf::protobuf)

install(TARGETS simple_proto DESTINATION lib)

add_executable(main main.cpp)
target_link_libraries(main PUBLIC simple_proto PRIVATE protobuf::protobuf)
target_include_directories(main PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

# ----- ***** ------
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
  set(protobuf_LIB_DIRS_ ${protobuf_LIB_DIRS_DEBUG})
  set(abseil_LIB_DIRS_ ${abseil_LIB_DIRS_DEBUG})
else()
  set(protobuf_LIB_DIRS_ ${protobuf_LIB_DIRS_RELEASE})
  set(abseil_LIB_DIRS_ ${abseil_LIB_DIRS_RELEASE})
endif()

file(GLOB PROTOBUF_OBJECTS
     ${protobuf_LIB_DIRS_}/*.so
     ${protobuf_LIB_DIRS_}/*.so.*)

file(GLOB ABSEIL_OBJECTS
     ${abseil_LIB_DIRS_}/*.so
     ${abseil_LIB_DIRS_}/*.so.*)

install(
  FILES
    ${PROTOBUF_OBJECTS} 
    ${ABSEIL_OBJECTS}
  DESTINATION lib)
# ----- ***** ------

install(TARGETS main DESTINATION bin)

conanfile.py:

from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout, CMakeToolchain


class ExampleConan(ConanFile):
    name="example"
    version="0.1"
    settings="os", "compiler", "build_type", "arch"
    options = {
        "shared": [True, False]
    }
    default_options = {
        "shared": True
    }
    generators = "CMakeDeps"

    requires = "protobuf/5.27.0"
    tool_requires = "protobuf/5.27.0"

    def generate(self):
        tc = CMakeToolchain(self)
        tc.generate()

    def layout(self):
        cmake_layout(self)

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()
    
    def package(self):
        cmake = CMake(self)
        cmake.install()

default profile:

[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux

jetson profile:

[settings]
arch=armv8
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
 
[buildenv]
CC=aarch64-linux-gnu-gcc
CXX=aarch64-linux-gnu-g++
STRIP="aarch64-linux-gnu-strip"
OBJDUMP="aarch64-linux-gnu-objdump"
LD="aarch64-linux-gnu-ld"

project:

~/Documents/test$ tree
.
├── CMakeLists.txt
├── conanfile.py
├── main.cpp
├── Makefile
└── simple.proto

main.cpp:

#include <iostream>
#include <string>

#include "simple.pb.h"


int main()
{
    MyMessage message;
    message.set_name("Hello, world!");

    std::string serialized;
    message.SerializeToString(&serialized);
    
    MyMessage new_message;
    new_message.ParseFromString(serialized);
    std::cout << "Deserialized: " << new_message.name() << std::endl;

    return 0;

}

simple.proto:

syntax = "proto3";

message MyMessage {
    string name = 1;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants