Unexpected linker errors

Hey guys,

I just recently purchased CLion and I'm running into an unexpected issue (for me atleast).

I created a new project and added 1 "class".  I then removed the actual class definition and instead implemented a static function (declaration in .h, definition .cpp).  However, I'm running into a linker error for said function.

I'm not really the strongest CMake user ever, but I was under the impression CMake would handle these dependencies for me.  I went so far as to run cmake directly from the console and go the same linker error, so it's a CMake issue rather than strictly a CLion issue, but I'm hoping for some guidance.

I'm sure that I'm doing something silly, but I don't know what I'm missing.

NOTE: I'm more than happy to zip/tar the entire project and send it to you as it's a fairly trivial project.

Below is the build output:

Scanning dependencies of target cpptest
[ 25%] Building CXX object CMakeFiles/cpptest.dir/main.cpp.o
[ 50%] Building CXX object CMakeFiles/cpptest.dir/Context.cpp.o
[ 75%] Linking CXX executable cpptest
CMakeFiles/cpptest.dir/main.cpp.o: In function `main':
/home/mreiland/dev/cpptest/main.cpp:17: undefined reference to `CPPTest::register_test(std::string, std::function<void ()>)'
/home/mreiland/dev/cpptest/main.cpp:20: undefined reference to `CPPTest::register_test(std::string, std::function<void ()>)'
collect2: error: ld returned 1 exit status


Below is the CMakeLists.txt file.

cmake_minimum_required(VERSION 3.3)
project(cpptest)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")

set(SOURCE_FILES main.cpp cpptest.cpp cpptest.h Context.cpp Context.h)
add_executable(cpptest ${SOURCE_FILES})


And the relevant source files

-- header file --

#ifndef CPPTEST_CPPTEST_H
#define CPPTEST_CPPTEST_H

#include <string>
#include <functional>

namespace CPPTest {
  /*
   * I'm considering just using a static interface for this.  not the greatest ever, but it is simple.  The state
   * would live in the translation unit itself behind an anonymous namespace.  Kind of terrible, but simple
   *
   *
   *
   * register_test(name,[](auto &thing) {
   *  thing.assert(stuff);
   * });
   */

  void register_test(std::string name, std::function<void()> cb);
}



#endif //CPPTEST_CPPTEST_H


-- cpp file --

#include "cpptest.h"

#include <vector>

namespace {
  struct TestInfo {
    std::string name;
    std::function<void(void)> test_callback;
  };

  std::vector<TestInfo> tests;
}

void register_test(std::string name, std::function<void(void)> cb) {
  TestInfo ti;
  ti.name = name;
  ti.test_callback = cb;
  tests.push_back(ti);
}

2 comments
Comment actions Permalink

Hi Michael.

Sorry for the delay. Your register_test function in the header file is in the CPPTest namespace and in source file it is in the global namespace, so these are different functions. To fix this, enclose register_test in source file in namespace CPPTest {} or change definition to void CPPTest::register_test.

0
Comment actions Permalink

Sorry, I should have followed up.  I woke up the next day and saw the issue immediately, that's what I get for coding while tired :)

0

Please sign in to leave a comment.