0

I've my discord bot project. The file structure of the relevant files are listed as below:

include/
    cpp-dotenv/
        dotenv.h
lib/
    libcpp_dotenv.a
src/
CMakeLists.txt

My simplified CMakeLists.txt:

cmake_minimum_required(VERSION 3.15)
set(BOT_NAME "tavernbot")
project(${BOT_NAME})

aux_source_directory(src mainsrc)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_executable(
        ${BOT_NAME}
        ${mainsrc})

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

target_include_directories(${BOT_NAME} PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/include
        )

target_link_libraries(${BOT_NAME}
        cpp_dotenv
        )

When I'm building I'm getting the following errors:

/usr/bin/ld: /mnt/e/my_bot/lib/libcpp_dotenv.a(dotenv.cpp.o): in function `dotenv::dotenv::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const':
dotenv.cpp:(.text+0x24): undefined reference to `dotenv::getenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: /mnt/e/my_bot/lib/libcpp_dotenv.a(dotenv.cpp.o): in function `dotenv::dotenv::load_dotenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool)':
dotenv.cpp:(.text+0x1e1): undefined reference to `dotenv::Parser::Parser()'
/usr/bin/ld: dotenv.cpp:(.text+0x1f6): undefined reference to `dotenv::Parser::parse(std::istream&, bool, bool)'
/usr/bin/ld: dotenv.cpp:(.text+0x220): undefined reference to `antlr4::tree::ParseTreeWalker::~ParseTreeWalker()'
/usr/bin/ld: /mnt/e/my_bot/lib/libcpp_dotenv.a(dotenv.cpp.o): in function `dotenv::Parser::~Parser()':
dotenv.cpp:(.text._ZN6dotenv6ParserD2Ev[_ZN6dotenv6ParserD5Ev]+0x1b): undefined reference to `antlr4::tree::ParseTreeWalker::~ParseTreeWalker()'
/usr/bin/ld: /mnt/e/my_bot/lib/libcpp_dotenv.a(dotenv.cpp.o): in function `dotenv::Parser::~Parser()':
dotenv.cpp:(.text._ZN6dotenv6ParserD0Ev[_ZN6dotenv6ParserD5Ev]+0x1b): undefined reference to `antlr4::tree::ParseTreeWalker::~ParseTreeWalker()'
collect2: error: ld returned 1 exit status
gmake[3]: *** [CMakeFiles/tavernbot.dir/build.make:134: tavernbot] Error 1
gmake[2]: *** [CMakeFiles/Makefile2:139: CMakeFiles/tavernbot.dir/all] Error 2
gmake[1]: *** [CMakeFiles/Makefile2:146: CMakeFiles/tavernbot.dir/rule] Error 2
gmake: *** [Makefile:169: tavernbot] Error 2

Could you tell me where I'm wrong in my CMakeLists.txt and why?

  • Where did you get the library from? Did you download and build it yourself? Does it need other libraries that it depends on? – Some programmer dude Aug 08 '23 at 08:04
  • I built it myself w/ `BUILD_SHARED_LIBS=OFF` from [repo](https://github.com/adeharo9/cpp-dotenv). Then I copied `libcpp_dotenv.a` and headers to my project. – Daniel Sinkevich Aug 08 '23 at 08:08
  • If you download and build yourself, why not place the whole cpp-dotenv project directory in a sub-directory of your own project, and `add_subdirectory(cpp-dotenv)` as suggested in readme? Then it would make sure that the `cpp_dotenv` target have all dependencies needed. And there's nothing to copy, and it would lower the chances or mistakes. – Some programmer dude Aug 08 '23 at 08:14
  • @Someprogrammerdude I want to prebuild that lib for faster project build in future. I have already done as you said, but I want a static library. – Daniel Sinkevich Aug 08 '23 at 08:20
  • @DanielSinkevich You can still build a static lib with `add_subdirectory` and `add_library`. Are you sure cmake finds the library instead of just skipped it? Maybe you should print all libs found to check that. If cmake does found the lib and linked it, the only reason to explain this is there are no such things required by your code in the lib. – LiuYuan Aug 08 '23 at 08:48

1 Answers1

0

If you look at the cpp-dotenv project structure you will see that dotenv library depends also on environ and parser libraries.

target_link_libraries(${CPP_DOTENV}
    ${ENVIRON_LIB}
    ${PARSER_LIB}
)

Then if you go deeper, you will see that those have even more dependencies from the project subdirectories.

So, either modify a bit the cpp-dotenv configuration to make it an installable package, and then find_package it in your CMakeLists.txt, or save yourself the trouble, and just embed that repository inside your project as-is. While developing, you need to compile it once, then if you make clean YOUR_GTARGET, the third party dependencies will stay already built in your project tree.

pptaszni
  • 5,591
  • 5
  • 27
  • 43