0

I have an include folder and an src folder, and i get a undefined reference error. My project previously worked so i have no idea what happened.

The error

$ cmake --build .
-- Configuring done
-- Generating done
-- Build files have been written to: /sdcard/dev/cpp/Bedrock++
Scanning dependencies of target Bedrock++
[ 33%] Building CXX object src/CMakeFiles/Bedrock++.dir/Server.cpp.o
[ 66%] Building CXX object src/CMakeFiles/Bedrock++.dir/main.cpp.o
[100%] Linking CXX executable Bedrock++
CMakeFiles/Bedrock++.dir/main.cpp.o: In function `main':
/sdcard/dev/cpp/Bedrock++/src/main.cpp:(.text+0x70): undefined 
reference to `ChatFormat::Blue'
clang-5.0: error: linker command failed with exit code 1 (use -v to see 
invocation)
make[2]: *** [src/CMakeFiles/Bedrock++.dir/build.make:121: 
src/Bedrock++] Error 1
make[1]: *** [CMakeFiles/Makefile2:86: 
src/CMakeFiles/Bedrock++.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

Project root CMakeLists.txt

cmake_minimum_required(VERSION 2.8.7)

# Build all dependent libraries as static

project(Bedrock++)

#add_subdirectory(lib/json)

add_subdirectory(src)
add_subdirectory(include)

src CMakeLists.txt

project(bedrock++)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

include_directories("${PROJECT_SOURCE_DIR}/include")

file(GLOB SOURCES "*.cpp")

add_executable(${PROJECT_NAME} ${SOURCES})

include CMakeLists.txt

install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" FILES_MATCHING PATTERN "*.h")

main.cpp

#include <iostream>
#include <string>
#include "util/ChatFormat.h"

int main()
{
    std::cout << "Hello World! " << ChatFormat::Blue << "hey" << std::endl;
}

The ChatFormat.h header is found in include/util/ChatFormat.h, and basically contains

static const std::string Black;

but for every different colour. Not sure if it's relevant, but the ChatFormat.cpp file contains the following throughout

const std::string ChatFormat::Delimiter = "\xc2\xa7";

const std::string ChatFormat::Black = ChatFormat::Delimiter + "0";
TheDiamondYT
  • 19
  • 1
  • 6
  • 1
    Please post the full text of the linker error ("Undefined reference") which you're getting (i.e. which reference is undefined?), and also the full declaration of `Blue` (including any containing namespace/class) in `ChatFormat,h`. It's hard to answer a question without having all the data, and you should make sure your questions always contain a [mcve]. – Angew is no longer proud of SO Oct 23 '17 at 12:42
  • @Angew Blue is the same as Black, except it has a different number in quotes (which shouldnt make any difference). I'll uldate it with the error – TheDiamondYT Oct 23 '17 at 13:05
  • You've shown the definition of `Black` in the `.cpp` file, but I was asking you to also show its declaration in the `.h`. – Angew is no longer proud of SO Oct 23 '17 at 13:08
  • @Angew I updated the question – TheDiamondYT Oct 23 '17 at 13:10
  • 1
    That update cannot be right, since you're accessing it as `ChatFormat::Blue` and the compiler is not complaining, but you've not shown any `ChatFormat` context around the declaration. Please provide **accurate** info if you want help. See my earlier comment: "including any containing namespace/class" – Angew is no longer proud of SO Oct 23 '17 at 13:12
  • Absolutely a duplicate – TheDiamondYT Oct 23 '17 at 22:14

2 Answers2

1

Header inclusion error

The problem with "Header file not found" is that your src/CMakeLists.txt contains a project() command. That declares a new CMake project (think Visual Studio solution) for that subtree. PROJECT_SOURCE_DIR will therefore refer to that project's source directory within that subtree. In other words, your ${PROJECT_SOURCE_DIR}/include resolves to ${CMAKE_SOURCE_DIR}/src/include.

Based on your CMake file structure, I'd say it makes no sense for src/CMakeLists.txt to contain a project() command. Just remove it, and include paths should start working for you.

Unresolved reference error

The question doesn't contain enough information to solve this, but my hunch is you're somehow messing up internal linkage (static) and definition in a dedicated source file. These normally don't mesh at all. You might want to read through the canonical Undefined Reference question here on Stack Overflow.

Community
  • 1
  • 1
Angew is no longer proud of SO
  • 161,995
  • 14
  • 331
  • 433
  • Thanks for the first solution :) For the second one i copied off https://github.com/cuberite/cuberite/blob/e1d3b201bd7a22f2924182f0243bb51433080c79/src/ChatColor.cpp and https://github.com/cuberite/cuberite/blob/e1d3b201bd7a22f2924182f0243bb51433080c79/src/ChatColor.h which seems to work there but not for me. Don't forget i mentioned that it worked before then i started changing directorh structure and stuff and it stopped working. Weird. – TheDiamondYT Oct 23 '17 at 12:49
  • @TheDiamondYT BTW, since you're using the *heavily discouraged* `file(GLOB)` to get your source file list: are you sure that `ChatFormat.cpp` is part of your source list? Is it on the same directory level as `main.cpp`? – Angew is no longer proud of SO Oct 23 '17 at 13:10
  • Oh wow. No it's not. How would i look for files in all directories then? – TheDiamondYT Oct 23 '17 at 13:21
  • @TheDiamondYT Follow [CMake's advice](https://cmake.org/cmake/help/latest/command/file.html) in the (`file(GLOB)` section) and list all files manually (you can dedicate a file to setting a variable and `include()` that file if you don't want to pollute your CMakeList). You'll save yourself a lot of trouble – Angew is no longer proud of SO Oct 23 '17 at 13:28
  • Thanks so much! – TheDiamondYT Oct 23 '17 at 14:39
0

The CMake output suggests that 'ChatFormat.cpp', which contains the definition of 'ChatFormat::Black', is not being compiled. Only 'Server.cpp' and 'main.cpp' are being compiled.

I'm guessing that 'ChatFormat.cpp', like it's corresponding header, is under a 'utils' directory? But the GLOB command you are using to find your source files will only be finding files name *.cpp in the root folder. You might want to try changing 'GLOB' to 'GLOB_RECURSE' so it will pick up files in subfolders, though it is generally recommended that you avoid using globbing entirely and list each source file explicitly...

Sean Burton
  • 830
  • 7
  • 15