Multiple definition with Protobuffer 3.7.1 generated files - c++

I try to compile some protocol-buffer files and I am getting the following errors.
[ 99%] Building CXX object CMakeFiles/lattice_planner.dir/modules/control/proto/lat_controller_conf.pb.cc.o
[100%] Linking CXX executable lattice_planner
CMakeFiles/lattice_planner.dir/modules/localization/proto/pose.pb.cc.o:(.bss+0x0): multiple definition of `apollo::localization::_Pose_default_instance_'
CMakeFiles/lattice_planner.dir/modules/common/localization/proto/pose.pb.cc.o:(.bss+0x0): first defined here
CMakeFiles/lattice_planner.dir/modules/localization/proto/pose.pb.cc.o: In function `apollo::localization::Pose::Pose()':
pose.pb.cc:(.text+0x4e8): multiple definition of `apollo::localization::Pose::Pose()'
CMakeFiles/lattice_planner.dir/modules/common/localization/proto/pose.pb.cc.o:pose.pb.cc:(.text+0x4e8): first defined here
The files are in different folders. Can I trick the compiler GCC 5.4.0 so that there are not multiple definitions?
The CMakeLists.txt is quite huge because I added all source files by hand. Here are some code snippets:
cmake_minimum_required(VERSION 3.5)
project(lattice_planner_src)
set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -pthread")
find_package(Protobuf 3.7.1 REQUIRED)
if(PROTOBUF_FOUND)
message ("log: protobuf found")
else()
message (FATAL_ERROR "Cannot find Protobuf")
endif()
add_executable(lattice_planner apollo-planner-test-main.cpp ${SOURCE_FILES} ${HEADER_FILES} ${PTB_SRC} ${PTB_HDR})
target_include_directories (
lattice_planner
PUBLIC
${Boost_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}
${PROTOBUF_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIR}
/usr/local/include/qpOASES
${TinyXML2_INCLUDE_DIR}
${IPOPT_INCLUDE_DIRS}
${GLOG_INCLUDE_DIR}
ctpl
)
target_link_libraries(lattice_planner
# EIGEN
${TinyXML2_LIBRARIES}
# ${GLOG_LIBRARY}
${IPOPT_LIBRARIES}
${Boost_LIBRARIES}
${PROTOBUF_LIBRARIES}
/usr/local/lib/libglog.so.0
/usr/local/lib/libqpOASES.a
${libgtest}
)
while the PTB_SRC and PTB_HDR are the protocol-buffer sources and headers. This project is already running on windows with MS projects. Unfortunately, I don't have any CMake for that. I am also happy for ideas and guesses.

Related

Target link Eigen library on Clion fails

I am trying to link eigen to my project on clion, but the following error is printed:
This is my cmakelist file with all the attempts to link the library:
cmake_minimum_required(VERSION 2.8.3)
project(planner_standalone_grasp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-diagnostics-color")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
# find all cpp files in currect directory (where CMakeLists.txt is)
file(GLOB SOURCE_FILES FILES_MATCHING PATTERN "./src/*.cpp")
include_directories(src)
add_executable(${PROJECT_NAME} main.cpp ${SOURCE_FILES})
set(EXE_LIBS
ctop_common
ctop_log
ctop_util
eigen
crl
crl-algorithm
crl-loader
crl-tsplib
yaml-cpp
)
target_link_directories(${PROJECT_NAME} PUBLIC lib/comrob/lib/)
target_link_directories(${PROJECT_NAME} PUBLIC ctop/common/cmake-build-debug/)
target_link_directories(${PROJECT_NAME} PUBLIC ctop/log/cmake-build-debug/)
target_link_directories(${PROJECT_NAME} PUBLIC ctop/util/cmake-build-debug/)
set(EIGEN_DIR "/usr/local/include/Eigen/")
include_directories(${EIGEN_DIR})
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
target_link_libraries (${PROJECT_NAME} Eigen3::Eigen)
target_link_directories(${PROJECT_NAME} PUBLIC lib/eigen/Eigen/)
target_link_directories(${PROJECT_NAME} PUBLIC /usr/local/include/Eigen/)
target_link_directories(${PROJECT_NAME} PUBLIC /usr/local/include/eigen3/Eigen/)
target_link_libraries(${PROJECT_NAME} ${EXE_LIBS})
All other libraries in the project are successfully linked except Eigen - This is the error message:
[6/6] Linking CXX executable planner_standalone_grasp
FAILED: planner_standalone_grasp
: && /usr/bin/c++ -O0 -fno-diagnostics-color -std=c++17 -g -rdynamic CMakeFiles/planner_standalone_grasp.dir/main.cpp.o CMakeFiles/planner_standalone_grasp.dir/src/Grasp.cpp.o CMakeFiles/planner_standalone_grasp.dir/src/WallEdge.cpp.o CMakeFiles/planner_standalone_grasp.dir/src/WallGraph.cpp.o CMakeFiles/planner_standalone_grasp.dir/src/pt2eigen.cpp.o -o planner_standalone_grasp -L/home/sim/CLionProjects/Test/lib/comrob/lib -L/home/sim/CLionProjects/Test/ctop/common/cmake-build-debug -L/home/sim/CLionProjects/Test/ctop/log/cmake-build-debug -L/home/sim/CLionProjects/Test/ctop/util/cmake-build-debug -L/home/sim/CLionProjects/Test/lib/eigen/Eigen -L/usr/local/include/Eigen -L/usr/local/include/eigen3/Eigen -Wl,-rpath,/home/sim/CLionProjects/Test/lib/comrob/lib:/home/sim/CLionProjects/Test/ctop/common/cmake-build-debug:/home/sim/CLionProjects/Test/ctop/log/cmake-build-debug:/home/sim/CLionProjects/Test/ctop/util/cmake-build-debug:/home/sim/CLionProjects/Test/lib/eigen/Eigen:/usr/local/include/Eigen:/usr/local/include/eigen3/Eigen -lctop_common -lctop_log -lctop_util -leigen -lcrl -lcrl-algorithm -lcrl-loader -lcrl-tsplib -lyaml-cpp && :
/usr/bin/ld: cannot find -leigen
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Any help would be highly appreciated!
In my experience there is two possible causes for this issue:
there is no library named libeigen. in the provided directories (the ones in target_link_directories). Perhaps the path is wrong?
You should know that usually library files are not located in the include directories of a repository...
there is a library named as such, though it was compiled for the wrong platform... i.e. a library compiled for linux cannot be linked if you are making an executable for windows. Usually you can find the source code and compile it yourself.
Hope this helps.

Linking of CUDA library in CMake

I am using CMake 3.10 and have a problem linking a compiled library to a test executable in CMake.
I searched a lot and found that in earlier versions there was a problem where you could not link intermediate libraries in the result executable. I was not able to tell if this was resolved or still an issue.
My CMake files look like this:
Algo:
cmake_minimum_required (VERSION 3.9)
project(${MODULE_NAME}_core LANGUAGES CXX CUDA)
add_subdirectory("${core_impl_dir}" implementation)
set(cuda_src "parallel/ParallelComputation.cu")
set(cuda_hdr "parallel/ParallelComputation.h")
add_library(${PROJECT_NAME} STATIC "${cuda_src}" "${cuda_hdr}"
)
target_include_directories (${PROJECT_NAME} PUBLIC "include/"
"parallel/"
)
source_group("parallel" FILES "${cuda_src}" "${cuda_hdr}")
set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${MODULE_NAME})
Test:
project(${MODULE_NAME}_gtest LANGUAGES CXX CUDA)
add_subdirectory("${gtest_impl_dir}" implementation)
add_executable(${PROJECT_NAME} "${gtest_impl_src}")
target_link_libraries(${PROJECT_NAME} ${MODULE_NAME}_core)
enable_testing()
find_package(GTest REQUIRED)
include_directories("${GTEST_INCLUDE_DIRS}")
target_link_libraries(${PROJECT_NAME} ${GTEST_BOTH_LIBRARIES})
source_group("Implementation\\Source Files" FILES "${gtest_impl_src}" )
set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER ${MODULE_NAME})
add_test(${PROJECT_NAME} ${PROJECT_NAME})
Building just Algo works fine, but when also building Test, I get linking errors, for example
../implementation/libmatrix1_testCuda_core.a(ParallelComputation.cu.o): In Funktion 'cudaError cudaMalloc(float**, unsigned long)':
tmpxft_00005ad0_00000000-5_ParallelComputation.cudafe1.cpp:(.text+0x4f2): Undefined reference 'cudaMalloc'
EDIT
using make VERBOSE=1 I got this linking command:
/usr/bin/c++ -Wl,--no-as-needed -pthread -g -std=c++14 -Wall
CMakeFiles/matrix1_testCuda_gtest.dir//tests/eclipseProject/algos/testCuda/test/src/main.cpp.o
CMakeFiles/matrix1_testCuda_gtest.dir/cmake_device_link.o -o
matrix1_testCuda_gtest ../implementation/libmatrix1_testCuda_core.a
/usr/lib/libgtest.a /usr/lib/libgtest_main.a
I got this to work by calling
find_package(CUDA 9.0 REQUIRED)
in both CMake files.
Also, in the Algo file (which contains the device code), I had to do
target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES})
I was expecting that the language support for CUDA would make those steps unnecessary, but apparently not.
I just ran into something very similar to this where the root problem was that most of my binary was being compiled with my system cxx compiler, and the cuda bits were being compiled with the cuda gcc compiler (9.1 for system, 8.3 for cuda).
Surprisingly it was fixed by changing:
project(MyProject LANGUAGES CXX CUDA)
to
project(MyProject LANGUAGES CUDA CXX)
After that change, CMake picked up the cuda version of the gcc compiler as the main compiler, and my binary started building again. I'm not sure if this could introduce problems for other packages, but it fixed the linking problem I was hitting.
Adding the possible way in CMake 3.18 and further
When you wish not to include any CUDA code, but e.g. using only calls to cufft from C++ it is sufficient to do the following
find_package(CUDAToolkit)
target_link_libraries(project CUDA::cudart)
target_link_libraries(project CUDA::cufft)
If you are however enabling CUDA support, unless you want to get into troubles call it after enabling CUDA.
include(CheckLanguage)
check_language(CUDA)
if(CMAKE_CUDA_COMPILER)
enable_language(CUDA)
find_package(CUDAToolkit)
target_link_libraries(project CUDA::cudart)
target_link_libraries(project CUDA::cuda_driver)
else()
message(STATUS "No CUDA compiler found")
endif()
Because CUDAToolkit respects enable CUDA runtime added but it does not work vice versa.

CMake and Make need to be run twice in order to build code successfully

I am using CMake 3.8.2, GNU make 4.2.1 and GCC 6.4.0 for my C++14 project and I noticed a strange behavior when building. I am using CMake for an out-of-source build in a sub-folder called "build" where I run cmake .. followed by make.
CMake runs fine without any errors and make will build all source files like I expect until it is done compiling and starts linking them. It will then fail with an error
[ 83%] ...
[100%] Linking CXX executable myproject
/usr/bin/ld: some-source-file.cc.o: undefined reference to symbol '_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv##GLIBCXX_3.4.21'
Interestingly it doesn't show any compiler warnings up to this point and only shows the above mentioned linker error.
Now when I ignore the error and simply run cmake .. and then make again (just like I did before) I get all the compiler warnings that my code should produce and everything links perfectly fine, even though I didn't change any code or CMake-related files in the meantime.
I can reproduce this behavior by deleting all files in the build dir by running rm -r *.
Here is my CMakeLists.txt file:
# Define minimum required CMake version
cmake_minimum_required(VERSION 3.8.2)
# Setting compiler related settings
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -O2 -lstdc++")
set(CMAKE_CXX_STANDARD 14)
# Define project name
project(MyProject)
# Find source files
file(GLOB_RECURSE SOURCES application/*.cc)
# Adding third-party sources
set(SOURCES ${SOURCES} "third-party/cpp-base64/base64.cpp")
# Executable to be built from which source files
add_executable(myproject ${SOURCES})
# Find and include and link Botan
find_library(BOTAN botan-2 "third-party/botan/build/lib")
include_directories("third-party/botan/build/include/botan-2")
# Includes that are part of the project
include_directories("${CMAKE_SOURCE_DIR}/application/include")
# Include nlohmann/json
include_directories("third-party/json/src")
# Include cpp-base64 by René Nyffenegger
include_directories("third-party/cpp-base64")
find_package(Boost REQUIRED COMPONENTS program_options)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
# Link third-party libraries
target_link_libraries(myproject ${Boost_LIBRARIES} ${BOTAN})
Note: I am required to check-in the compiler and libraries I am using, which is why I specified them in the CMake file.
If it only works the second time it has to do with cached variables.
So I'm pretty sure that it will work the first time if you modify CMAKE_CXX_COMPILER setting by adding set(... CACHE INTERNAL "") to:
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc" CACHE INTERNAL "")
And move set(CMAKE_CXX_FLAGS ...) after the project() command.
But please also be noted that you shouldn't put the compiler into your CMakeLists.txt.
References
CMake: In which Order are Files parsed (Cache, Toolchain, …)?
Passing compiler options cmake
CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found

Static linking DCMTK library

I use DCMTK in my application and for compilation use cmake file. cmake finds all libraries (at least headers, because in compiles source files to .o files) the only problem is that during linking it tries to find dynamic libraries for DCMTK. I compiled one as static, so I do not have .so files. As a result it gives me error :No rule to make target /usr/lib/libdcmdata.so, needed by dcm_seg. Stop.
I use Ubuntu 14.04 x64.
It confuses me pretty much. So, what's the problems?
cmake file:
cmake_minimum_required(VERSION 2.6)
project(dcm_segm)
set(CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS} -g -ftest-coverage -fprofile-arcs")
set(Boost_USE_STATIC_LIBS ON)
set(OpenCV_USE_STATIC_LIBS ON)
set(DCMTK_USE_STATIC_LIBS ON)
set(OpenCV_STATIC ON)
find_package( VTK REQUIRED )
find_package( OpenCV REQUIRED )
find_package( Boost COMPONENTS system filesystem REQUIRED )
find_package( DCMTK REQUIRED )
include(${VTK_USE_FILE} )
link_directories(${OpenCV_LIB_DIR})
add_executable(dcm_seg main.cpp DICOMin.cpp Ensemble.cpp Ensemble3dExtension.cpp point_3d.cpp RegionGrow.cpp)
target_link_libraries(dcm_seg ${VTK_LIBRARIES} ${OpenCV_LIBS} ${DCMTK_LIBRARIES} ${Boost_LIBRARIES})
Can you check the content of ${DCMTK_LIBRARIES} (it should be a list of paths to DCMTK static libraries) ?
you can also check the following CMake entries during the CMake configuration:
DCMTK_DIR /path/to/DCMTK/install
DCMTK_config_INCLUDE_DIR /path/to/DCMTK/install/include/dcmtk/config
DCMTK_dcmdata_INCLUDE_DIR /path/to/DCMTK/install/dcmdata/include/dcmtk/dcmdata
DCMTK_dcmdata_LIBRARY_DEBUG /path/to/DCMTK/install/dcmdata/libsrc/libdcmdata.a
DCMTK_dcmdata_LIBRARY_RELEASE /path/to/DCMTK/install/dcmdata/libsrc/libdcmdata.a
[...]
Another hint: I noted in the past that find DCMTK from a build instead of an install not always works properly.
If you have trouble finding DCMTK with the script provided with CMake
(${DCMTK_LIBRARIES} doesn not content the path to you static DCMTK libs for example) you can try to use this alternative script

CMake third party library undefined reference

I already read and searched a lot (e.g. 1 2 3, several docs for CMake, similar projects, etc. to find a solution but I have not been able to solve my problem. I am relatively new to Cmake and Linux (Ubuntu 14.04).
I want to use libsbp (https://github.com/swift-nav/libsbp) to write a program in C++ to communicate with a GPS module. I cloned the repository and installed the C-Library. So now in /usr/local/lib there are two files: libsbp.so and libsbp-static.a and the headers are in /usr/local/include/libsbp
In my own project I include the headers with #include "libsbp/sbp.h" which also works.
Now the Problem: if I want to use a method from libsbp e.g. sbp_state_init(&s); I get undefined reference to "sbp_state_init(sbp_state_t*)"
The relevant part of my Cmake for my own project:
link_directories(/usr/local/lib)
add_executable(main ${QT_SOURCES} ${QT_HEADER_HPP})
target_link_libraries(main ${QT_LIBRARIES} ${catkin_LIBRARIES} sbp)
As I said before, I tried some things:
find_library(SBP_LIB sbp /usr/local/lib) -> same error
same goes for using libsbp in target_link_libraries or searching for it
link_directory(/usr/local/lib)
trying different paths, even moveing libsbp.so into the project directory and "finding" it with ${CMAKE_CURRENT_SOURCE_DIR}
Maybe you can help me!
edit:
this is the CMakeList.txt from the libsbp/c/src directory
if (NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS ON)
endif (NOT DEFINED BUILD_SHARED_LIBS)
file(GLOB libsbp_HEADERS "${PROJECT_SOURCE_DIR}/include/libsbp/*.h")
include_directories("${PROJECT_SOURCE_DIR}/CBLAS/include")
include_directories("${PROJECT_SOURCE_DIR}/clapack-3.2.1-CMAKE/INCLUDE")
include_directories("${PROJECT_SOURCE_DIR}/lapacke/include")
include_directories("${PROJECT_SOURCE_DIR}/include/libsbp")
set(libsbp_SRCS
edc.c
sbp.c
)
add_library(sbp-static STATIC ${libsbp_SRCS})
install(TARGETS sbp-static DESTINATION lib${LIB_SUFFIX})
if(BUILD_SHARED_LIBS)
add_library(sbp SHARED ${libsbp_SRCS})
install(TARGETS sbp DESTINATION lib${LIB_SUFFIX})
else(BUILD_SHARED_LIBS)
message(STATUS "Not building shared libraries")
endif(BUILD_SHARED_LIBS)
install(FILES ${libsbp_HEADERS} DESTINATION include/libsbp)
this is the CMakeList.txt from /libsbp/c/
cmake_minimum_required(VERSION 2.8.9)
project(libsbp)
# Setup flags for Code Coverage build mode
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used by the C++ compiler for building with code coverage."
FORCE )
set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used by the C compiler for building with code coverage."
FORCE )
SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE
"${CMAKE_EXE_LINKER_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used for linking binaries with code coverage."
FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} --coverage" CACHE STRING
"Flags used by the shared libraries linker during builds with code coverage."
FORCE )
mark_as_advanced(
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
# Update the documentation string of CMAKE_BUILD_TYPE for GUIs
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage."
FORCE )
# Set project version using Git tag and hash.
execute_process(
COMMAND git describe --dirty --tags --always
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
RESULT_VARIABLE GIT_VERSION_FOUND
ERROR_QUIET
OUTPUT_VARIABLE GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (GIT_VERSION_FOUND)
set(VERSION "unknown")
else (GIT_VERSION_FOUND)
set(VERSION ${GIT_VERSION})
endif (GIT_VERSION_FOUND)
# Set project version explicitly for release tarballs.
#set(VERSION foo)
message(STATUS "libsbp version: ${VERSION}")
cmake_minimum_required(VERSION 2.8)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# Some compiler options used globally
set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-strict-prototypes -Wno-unknown-warning-option -Werror -std=gnu99 ${CMAKE_C_FLAGS}")
add_subdirectory(src)
add_subdirectory(docs)
add_subdirectory(test)
It seems that your program uses C++ and the library is written in C.
Symbols in C and C++ are encoded differently (mangled). When including C headers from C++ you need to tell the compiler. This can be done by declaring the symbols extern "C".
extern "C" {
#include <libsbp/sbp.h>
}
Some libraries already include this in their headers, but not sbp.
You have (at least) two possibilities:
Installing the library (this is what you did)
Integrating the library in your CMake project
When installing the library, the target_link_libraries command needs to be modified slightly:
find_library(SBP_LIB sbp /usr/local/lib)
target_link_libraries(main ${QT_LIBRARIES} ${catkin_LIBRARIES} ${SBP_LIB})
When you integrate the library in your CMake project, you can directly use the following command without using find_library. This works, because the library is known to CMake since it is built within the current project.
target_link_libraries(main ${QT_LIBRARIES} ${catkin_LIBRARIES} sbp)