3

I have a cmake file which generates my helloworld.workspace to work from. How do i get my cmake to include header files from a directory and external libraries example. -glfw3 like how i would normally use when using gcc directly. Note: i am on ubuntu. Any help is appreciated.

CMakeLists.txt

cmake_minimum_required (VERSION 3.5)

project (HelloWorld)

set (CMAKE_CXX_fLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++14")
set (source_dir "${PROJECT_SOURCE_DIR}/src/")

add_executable (HelloWorld ${source_files})

build.sh (To run cmake)

#!/bin/sh

cmake . -G "CodeLite - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug

My folder looks like this

-HelloWorldProject
   -CMakeLists.txt
   -build.sh
   -src
      -main.cpp
   -includes
      -(heres where i will put my .h and .cpp includes)
rial
  • 705
  • 7
  • 17
  • [`target_include_directories`](https://cmake.org/cmake/help/latest/command/target_include_directories.html)? – Alan Birtles Nov 03 '20 at 19:42
  • 1
    StackOverflow is not a substitute for reading the manual. Please revise the `target_include_directories` and `target_link_libraries` documentation. For a more tutorializing approach, read [An introduction to modern CMake](https://cliutils.gitlab.io/modern-cmake/). – Botje Nov 03 '20 at 19:44
  • 1
    `and .cpp includes` Don't include .cpp files. – eerorika Nov 03 '20 at 19:49
  • thankyou for the comments but i have been experiencing this error with my includes in cmake `CMake Error at CMakeLists.txt:10 (target_include_directories)` – rial Nov 03 '20 at 19:59

2 Answers2

2

You need to tell CMake to add includes/to your program's include path. Usually this is done with either include_directories or target_include_directories

add_executable (HelloWorld ${source_files})

# Assuming this is meant to be a public directory
target_include_directories(HelloWorld PUBLIC "includes/")
Human-Compiler
  • 11,022
  • 1
  • 32
  • 59
1

The initial answer given by Human-Compiler works just fine; however, since the question was specifically how to include the header files, here is a slightly different approach that does just that by recursively searching subdirectories for files with matching extensions:

set( SOURCE_PATH "${PROJECT_SOURCE_DIR}/src" )
set( INCLUDE_PATH "${PROJECT_SOURCE_DIR}/include" )

file( GLOB_RECURSE HPPS "${INCLUDE_PATH}/*.hpp" )
file( GLOB_RECURSE CPPS "${SOURCE_PATH}/*.cpp" )

add_executable( ${TARGET} ${CPPS} ${HPPS} )

Here's an example of what your CMakeLists.txt file could look like:

cmake_minimum_required( VERSION 3.21 )
project( HelloWorld LANGUAGES CXX )

set( TARGET ${PROJECT_NAME} )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin )

set( SOURCE_PATH "${PROJECT_SOURCE_DIR}/src" )
set( INCLUDE_PATH "${PROJECT_SOURCE_DIR}/include" )

file( GLOB_RECURSE HPPS "${INCLUDE_PATH}/*.hpp" )
file( GLOB_RECURSE CPPS "${SOURCE_PATH}/*.cpp" )

add_executable( ${TARGET} ${CPPS} ${HPPS} )

target_include_directories( ${TARGET} PUBLIC ${INCLUDE_PATH} )
target_compile_options( ${TARGET} PRIVATE -Wall -Wextra -Wshadow -Wconversion -Wsign-conversion -Wunused-parameter -Wno-long-long -pedantic )
target_compile_features( ${TARGET} PRIVATE cxx_std_14 )

install( 
    TARGETS ${TARGET} 
    RUNTIME DESTINATION 
)

This is helpful in scenarios where other file types may exist in the subdirectory being searched. In CMake, it's not uncommon for .inl files to wind up in the include directory. This method allows for much more specificity on the desired file type.

"...and external libraries example. -glfw3 like how i would normally use when using gcc directly..."

Do this by first finding the package(s). For GLFW, also search for OpenGL.

find_package( OpenGL REQUIRED )
find_package( glfw3 REQUIRED )

Be sure to call add_executable() BEFORE linking them to the target:

add_executable()
target_link_libraries( ${TARGET} PUBLIC ${OPENGL_gl_LIBRARY} glfw3 )