1

I am brand new to CMake and have been reading through blogs to get this to work. I had a cmake file working when all the files were in the same directory but can't seem to get this to work - the include dir was giving me trouble. In this last attempted I was referencing this stack overflow thread. This was the closest I came to getting this to work. Please help.

File Tree

$ tree
.
├── CMakeLists.txt
├── include
│   ├── CMakeLists.txt
│   └── math.h
├── src
│   ├── CMakeLists.txt
│   └── math.c
└── testy
    ├── CMakeLists.txt
    └── math.cpp

3 directories, 7 files

CMake Files

$ more CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(iamtesting)
enable_testing()
add_subdirectory(include)
add_subdirectory(src)
add_subdirectory(testy)
$ more include/CMakeLists.txt
add_library(include INTERFACE)
target_include_directories(include INTERFACE ./)
$ more src/CMakeLists.txt
add_library(src STATIC math.c)
target_include_directories(src PUBLIC ./)
$ more testy/CMakeLists.txt
set(TEST_EXE_NAME math)
add_executable(${TEST_EXE_NAME} math.cpp)
target_include_directories(${TEST_EXE_NAME} PUBLIC ./)
target_link_libraries(${TEST_EXE_NAME} src)
add_test(NAME "testDatabase" COMMAND ${TEST_EXE_NAME})

CMake

$ cmake CMakeLists.txt
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jason/gtest

Make

$ make
Scanning dependencies of target src
[ 25%] Building C object src/CMakeFiles/src.dir/math.c.o
/home/jason/gtest/src/math.c: In function ‘main’:
/home/jason/gtest/src/math.c:5:24: warning: implicit declaration of function ‘sum’ [-Wimplicit-function-declaration]
   printf("10+20=%d\n", sum(10,20));
                        ^~~
[ 50%] Linking C static library libsrc.a
[ 50%] Built target src
Scanning dependencies of target math
[ 75%] Building CXX object testy/CMakeFiles/math.dir/math.cpp.o
In file included from /usr/include/gtest/gtest.h:1874:0,
                 from /home/jason/gtest/testy/math.cpp:1:
/home/jason/gtest/testy/math.cpp: In member function ‘virtual void widget_ok_Test::TestBody()’:
/home/jason/gtest/testy/math.cpp:5:13: error: ‘sum’ was not declared in this scope
   ASSERT_EQ(sum(1, 1), 2);
             ^
/home/jason/gtest/testy/math.cpp:5:3: error: template argument 1 is invalid
   ASSERT_EQ(sum(1, 1), 2);
   ^
testy/CMakeFiles/math.dir/build.make:62: recipe for target 'testy/CMakeFiles/math.dir/math.cpp.o' failed
make[2]: *** [testy/CMakeFiles/math.dir/math.cpp.o] Error 1
CMakeFiles/Makefile2:158: recipe for target 'testy/CMakeFiles/math.dir/all' failed
make[1]: *** [testy/CMakeFiles/math.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2

Src Files

$ more src/math.c
#include <stdio.h>
#include "math.h"

int main() {
  printf("10+20=%d\n", sum(10,20));
  return 0;
}

int sum(int x, int y) {
    return x + y;
}
$ more include/math.h
#define _MATH_H_

int sum(int, int);
$ more src/math.c
#include <stdio.h>
#include "math.h"

int main() {
  printf("10+20=%d\n", sum(10,20));
  return 0;
}

int sum(int x, int y) {
    return x + y;
}
$ more testy/math.cpp
#include "gtest/gtest.h"
#include "math.h"

TEST(widget, ok) {
  ASSERT_EQ(sum(1, 1), 2);
}

int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
user3746195
  • 346
  • 1
  • 16
  • 1
    It looks like your `#include "math.h"` directive actually includes **standard C header** [math.h](https://man7.org/linux/man-pages/man0/math.h.0p.html), not your header `include/math.h`. It is better to NOT name your own headers as the standard ones. Moreover, your header is simply not accessible from the `src` and `math` executables, since you don't link `include` library which provides path your `math.h` header. – Tsyvarev Aug 20 '20 at 07:57

1 Answers1

0

There are quite a few issues with your setup:

  1. libInclude (defined in include/CMakeLists.txt) is not needed. You need to create one lib, libSrc, that has include directory added via target_include_directories.
  2. src folder shall not be added via target_include_directories as it only stores source files which are implementation of your functionality and shall never be actually used as #includes anywhere.
  3. there shall be only one main function in every program, so most probably you shall remove main from src/math.c. You should have one main.cpp for your executable that will link libSrc and one main method for your tests (math.cpp in your case, you're linking the libSrc correctly there)
  4. include/math.h shall have proper include guard
Quarra
  • 2,527
  • 1
  • 19
  • 27