google / libkml

Reference implementation of OGC KML 2.2
Other
95 stars 55 forks source link

undefined reference to `kmlbase::intrusive_ptr_release(kmlbase::Referent*)' #19

Closed kulakovaanna closed 2 years ago

kulakovaanna commented 2 years ago

Hello, I'm trying to use libKML and I can successfully use " #include "kml/dom.h" " and "using namespace kmldom;". But if I try to use any function or type from libKML, I'm getting an error:

[main] Building folder: l3_kml 
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /home/ftn21/Documents/MAI/7sem/asbis/LB/realiziation/lb/l3_kml/build --config Debug --target all -j 6 --
[build] [1/1 100% :: 0.110] Linking CXX executable kml
[build] FAILED: kml 
[build] : && /usr/bin/clang++-9 -g  CMakeFiles/kml.dir/main.cpp.o -o kml   && :
[build] CMakeFiles/kml.dir/main.cpp.o: In function `~intrusive_ptr':
[build] /usr/include/boost/smart_ptr/intrusive_ptr.hpp:98: undefined reference to `kmlbase::intrusive_ptr_release(kmlbase::Referent*)'
[build] clang: error: linker command failed with exit code 1 (use -v to see invocation)
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1

Here is my CMakeLists.txt file:

cmake_minimum_required (VERSION 3.2)
# Set language standard
set(CMAKE_CXX_STANDARD "11")
project (kml)

# Set default build type to RelWithDebInfo if not specified
if (NOT CMAKE_BUILD_TYPE)
    message (STATUS "Default CMAKE_BUILD_TYPE not set using Release with Debug Info")
    set (CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE
        STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel"
        FORCE)
endif()

# linking kml library
find_package(LibKML)
if(NOT LibKML_FOUND)
    message(SEND_ERROR "Failed to find LibKML.")
    return()
else()
    include_directories(${LibKML_INCLUDE_DIRS})
endif()

add_executable (kml main.cpp)

target_include_directories(kml PUBLIC ${LibKML_INCLUDE_DIRS}) 
target_link_libraries(kml ${LibKML_LIBRARIES})

Here is the executable file main.cpp:

#include <iostream>
#include <string>
#include "kml/dom.h"

using namespace std;
using namespace kmldom;

int main() {
  cout << "hello world" << endl;

  ElementPtr element;  // error here

  return 0;
}

I use linux ubuntu 18.04.6 LTS, CMake 3.22.0, Clang 9.0.0

kulakovaanna commented 2 years ago

The solution was to write all paths (to libkml headers and to all libkml *.so files) in CMakeLists.txt. Otherwise cmake can't find them. I additionally linking Boost library, but in the rest the CMakeLists.txt should contain such instructions:

cmake_minimum_required (VERSION 3.2)
# Set language standard
set(CMAKE_CXX_STANDARD "11")
project (test_proj)

add_definitions(-std=c++11)

# Set default build type to RelWithDebInfo if not specified
if (NOT CMAKE_BUILD_TYPE)
    message (STATUS "Default CMAKE_BUILD_TYPE not set using Release with Debug Info")
    set (CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE
        STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel"
        FORCE)
endif()

# linking boost library
find_package(Boost COMPONENTS system filesystem thread REQUIRED)
if(NOT Boost_FOUND)
    message(SEND_ERROR "Failed to find boost.")
    return()
else()
    include_directories(${Boost_INCLUDE_DIRS})
endif()

add_executable(test_proj main.cpp)

set (LibKML_INCLUDE_DIRS /usr/include/kml/)
set (LibKML_LIBRARIES /usr/lib/x86_64-linux-gnu/libkmlbase.so /usr/lib/x86_64-linux-gnu/libkmlconvenience.so /usr/lib/x86_64-linux-gnu/libkmldom.so /usr/lib/x86_64-linux-gnu/libkmlengine.so /usr/lib/x86_64-linux-gnu/libkmlregionator.so /usr/lib/x86_64-linux-gnu/libkmlxsd.so)

message("LibKML is at: ${LibKML_INCLUDE_DIRS} and ${LibKML_LIBRARIES}")
message("Boost is at: ${Boost_INCLUDE_DIRS} and ${Boost_LIBRARIES}")

target_include_directories(test_proj 
PUBLIC 
${LibKML_INCLUDE_DIRS} 
${Boost_INCLUDE_DIRS} ) 

target_link_libraries(test_proj 
PUBLIC
${LibKML_LIBRARIES} ${Boost_LIBRARIES})

install(TARGETS test_proj EXPORT test_proj_export)
export(EXPORT test_proj_export FILE cmake/test_proj-targets.cmake)