Help with tutorial step 2

Hello. I am trying to learn CMake using the Tutorial. I am at Step 2.

The contents of my main CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)

# set the project name and version
project(Tutorial VERSION 1.0)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)

if(USE_MYMATH)
  add_subdirectory(MathFunctions)
  list(APPEND EXTRA_LIBS MathFunctions)
  list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()

# add the executable
add_executable(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           ${EXTRA_INCLUDES}
                           )

Upon building I am getting the error:

Scanning dependencies of target MathFunctions
[ 25%] Building CXX object MathFunctions/CMakeFiles/MathFunctions.dir/mysqrt.cxx.o
[ 50%] Linking CXX static library libMathFunctions.a
[ 50%] Built target MathFunctions
Scanning dependencies of target Tutorial
[ 75%] Building CXX object CMakeFiles/Tutorial.dir/tutorial.cxx.o
/home/samjnaa/sr/_repos/git/cmake/Help/guide/tutorial/Step2copy/tutorial.cxx:26:30: error: use of undeclared identifier 'mysqrt'
  const double outputValue = mysqrt(inputValue);
                             ^
1 error generated.
make[2]: *** [CMakeFiles/Tutorial.dir/build.make:63: CMakeFiles/Tutorial.dir/tutorial.cxx.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:96: CMakeFiles/Tutorial.dir/all] Error 2
make: *** [Makefile:84: all] Error 2

Please advise as to what I’m doing wrong. Please ask if I need to post the contents of any other file as well. Thanks!

The CMake file looks perfect. Have you forgotten to add the new include to tutorial.cxx?

#ifdef USE_MYMATH
#  include "MathFunctions.h"
#endif

I have included it, nothing missing.

The files in Step3 are the expected result if you do everything from Step2.
Can you please compare your files against the ones from Step3 to see if there are any relevant differences?

1 Like

Can you post the contents of the CMakeLists.txt in the MathFunctions subdirectory?

It’s just

 add_library(MathFunctions mysqrt.cxx)

No, there are only a couple of comment lines extra.

Based on the compiler error message, the function prototype of mysqrt is missing.
This can be caused by not including the header with the Prototype, including another header file with the same name but without prototype or by a misspelled function name.

Can you please add a warning into the MathFunctions.h to check if it really was included:

#warning Header included

The output of you make should look like this:

Scanning dependencies of target MathFunctions
[ 25%] Building CXX object MathFunctions/CMakeFiles/MathFunctions.dir/mysqrt.cxx.o
In file included from /home/u/cmake/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx:3:
/home/u/cmake/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h:1:2: warning: #warning Header included [-Wcpp]
 #warning Header included
  ^~~~~~~
[ 50%] Linking CXX static library libMathFunctions.a
[ 50%] Built target MathFunctions
Scanning dependencies of target Tutorial
[ 75%] Building CXX object CMakeFiles/Tutorial.dir/tutorial.cxx.o
In file included from /home/u/cmake/Help/guide/tutorial/Step3/tutorial.cxx:10:
/home/u/cmake/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.h:1:2: warning: #warning Header included [-Wcpp]
 #warning Header included
  ^~~~~~~
[100%] Linking CXX executable Tutorial
[100%] Built target Tutorial

So you can see, that the header was really included by both .cxx files.

Perhaps it may help if you clone the CMake repo and work direct with the tutorial:

bash-3.2$ git status .
Auf Branch develop
nichts zu committen, Arbeitsverzeichnis unverändert
bash-3.2$ git remote -v
origin	https://gitlab.kitware.com/cmake/cmake.git (fetch)
origin	https://gitlab.kitware.com/cmake/cmake.git (push)
bash-3.2$ pwd
/Users/clausklein/Downloads/cmake/Help/guide/tutorial
bash-3.2$ ll Step2
total 24
-rw-r--r--   1 clausklein  staff   615B  5 Jul  2020 CMakeLists.txt
drwxr-xr-x   4 clausklein  staff   128B  5 Jul  2020 MathFunctions/
-rw-r--r--   1 clausklein  staff   164B  5 Jul  2020 TutorialConfig.h.in
drwxr-xr-x   6 clausklein  staff   192B  5 Jul  2020 ./
-rw-r--r--   1 clausklein  staff   701B  5 Jul  2020 tutorial.cxx
drwxr-xr-x  16 clausklein  staff   512B 26 Feb  2021 ../
bash-3.2$ 

Sorry in my earlier reply I had compared only the CMakeLists.txt. Now I compared the whole directories and found my mistake:

#include "TutorialConfig.h"

#ifdef USE_MYMATH
#  include "MathFunctions.h"
#endif

In my files I had included the #ifdef USE_MYMATH etc at the top of the file and hence it couldn’t read the USE_MYMATH from the TutorialConfig.h file…

The relevant part of the tutorial:

in tutorial.cxx, include the MathFunctions.h header if we need it:

#ifdef USE_MYMATH 
# include "MathFunctions.h" 
#endif

It would be good to have an admonishment to include this after the #include "TutorialConfig.h" line.

Is this part from the tutorial related to the above?:

Exercise: Why is it important that we configure TutorialConfig.h.in after the option for USE_MYMATH? What would happen if we inverted the two?

Good to hear that the problem is identified.

The exercise refers to this CMake code:

option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)

Which is about the same problem, but for CMake not C: Do not use a symbol before its definition.
So probably there should be added a hint or the complete code of the inclusion to the tutorial.

Yes now I can see that and have tested it. Thanks.

But this is a CMake tutorial, not a C tutorial. The complete code is already available, quoting from the webpage:

The tutorial documentation and source code for examples
can be found in the Help/guide/tutorial directory of the
CMake source code tree.

If a hint should be added, I would suggest adding it in the form of an exercise at the bottom of the page.