Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why is my variable definition not visible in my target_link_libraries usage site at a higher directory scope than the one the variable was defined in?

I am having issue with correctly linking/including a library in my c++ project. I have followed other posts and used add_subdirectory, target_include_directories, and target_link_libraries in CMakeLists.txt.
But I am still getting the following error during make.

test_app/main.cc:3:10: fatal error: icalendar.h: No such file or directory
 #include "icalendar.h"
          ^~~~~~~~~~~~~
compilation terminated.
CMakeFiles/program.dir/build.make:75: recipe for target 'CMakeFiles/program.dir/main.cc.o' failed
make[2]: *** [CMakeFiles/program.dir/main.cc.o] Error 1
CMakeFiles/Makefile2:117: recipe for target 'CMakeFiles/program.dir/all' failed
make[1]: *** [CMakeFiles/program.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2

The project structure looks like this:

.
├── CMakeLists.txt
├── icalendarlib
│   ├── CMakeLists.txt
│   ├── date.cpp
│   ├── date.h
│   ├── icalendar.cpp
│   ├── icalendar.h
│   ├── README.rst
│   ├── test
│   │   ├── calendar.ics
│   │   ├── CMakeLists.txt
│   │   └── iCalendarTest.cpp
│   ├── types.cpp
│   ├── types.h
│   └── wxwrapper.h
└── main.cc

The project’s CMake looks like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#./CMakeLists.txt
cmake_minimum_required(VERSION 3.6)
project(test_app)

add_subdirectory(icalendarlib)

add_executable (program main.cc)

target_link_libraries(program ${LIB_OUTPUT_NAME})

The library’s cmake looks like this:

#./icalendarlib/CMakeLists.txt
project(iCalendarlib)
set(LIB_OUTPUT_NAME iCalendar)

set(CFLAGS "-g")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CFLAGS}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CFLAGS}")

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_library(${LIB_OUTPUT_NAME} SHARED
    date.cpp
    date.h
    icalendar.cpp
    icalendar.h
    types.cpp
    types.h
)

target_include_directories(${LIB_OUTPUT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/icalendarlib)

main.cc looks like this

#include "icalendar.h" // << fatal error: icalendar.h: No such file or directory
int main () {
  return 0;
}

I am running these commands under build folder

cmake .. 
make

>Solution :

There’s a rule I try to follow in CMake: don’t use variables if you don’t really have to.

For example, you could just link to the library directly instead of using a variable equals to the name of your library:

target_link_libraries(program iCalendar)

But here’s the problem: variables in CMake are scoped by directory. When you do this

target_link_libraries(program ${LIB_OUTPUT_NAME})

You’re not linking to any library since you set the value in the subdirectory only.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading