CMake not finding proper header/include files in include_directories

12,286

The main problem here is that you're referring to the SOURCE_FILES target as if it was a variable. Remove the dollar sign and curly braces.

target_link_libraries(Framework SOURCE_FILES)

It also seems kind of weird that you set include_directories after calling add_subdirectory, I'd be surprised if that worked.

Overall I think you're making things more complicated than they need to be. The following should be all that's necessary.

Top level CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(Framework CXX)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -pedantic")

include_directories(
  ${PROJECT_SOURCE_DIR}/Headers
)

add_subdirectory(Source)

Source/CMakeLists.txt

# Do not use file globing because then CMake is not able to tell whether a file
# has been deleted or added when rebuilding the project.
set(HELLO_LIB_SRC
  hello.cc
)
add_library(hello ${HELLO_LIB_SRC})

set(MAIN_SRC
  main.cc
)
add_executable(hello_bin ${MAIN_SRC})
target_link_libraries(hello_bin hello)

Headers/hello.h

#pragma once

#include <string>

namespace nope
{
  std::string hello_there();
}

Source/hello.cc

#include <hello.h>

namespace nope
{
  std::string hello_there()
  {
    return "Well hello there!";
  }
}

Source/main.cc

#include <hello.h>
#include <iostream>

int main()
{
  std::cout << nope::hello_there() << std::endl;
  return 0;
}

Do not worry about the placement of files in the build folder. That's for the install step to figure out.

$ mkdir build && cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
Share:
12,286
lilott8
Author by

lilott8

I'm a grad student pretending to know something about computer science. One day I hope I'm no longer pretending....

Updated on June 04, 2022

Comments

  • lilott8
    lilott8 almost 2 years

    Once again I am getting a "undefined symbols for architecture x86_64" error when I try to compile. I've tried more than I can actually document in this post (because I've forgotten all that I have tried). It is a really simple set-up and should compile very easily with CMake...

    When I run a make on this it works just fine. But I want to convert it to CMake for interoperability. As you can see I have thrown my "${HEADERS}" variable in a few places, I've tried quite a few placements of it but I keep getting my error. Depending on where I put that ${HEADER} it can also technically generate an error of "error: cannot specify -o when generating multiple output files" (That applies if it only sits in the target_link_library declaration).

    I have 2 folders:

    Root
        Headers (contains all .h files)
        Source (contains all .cc/.cpp/.c files) (and also a CMakeLists.txt)
    CMakeLists.txt
    

    My root CMakeLists.txt contains the following:

    cmake_minimum_required(VERSION 2.8.4)
    project(Framework)
    
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    add_compile_options("-v")
    
    add_subdirectory(Source)
    
    #Variables for making my life easier and adding the headers
    set(H Headers)
    include_directories(${H})
    set(S Source)
    file(GLOB HEADERS
    #Add any file in the headers dir
    "${H}/*"
    )
    
    # Create a variable to use for main.cc
    set(MAIN ${S}/main.cc ${HEADERS})
    
    # Add the main.cc file and headers
    add_executable(Framework ${MAIN} ${HEADERS})
    
    # Add the .cc/.cpp files
    target_link_libraries(Framework ${SOURCE_FILES})
    

    My CMakeLists.txt in my source directory contains the following:

    file(GLOB SOURCES
    "*.cc"
    "*.cpp"
    )
    
    add_library(SOURCE_FILES ${SOURCES})
    

    I do not have one in the headers as per, what I believe, the documentation states we don't need.

    Thanks for the help. I've looked at:

  • lilott8
    lilott8 over 9 years
    You sir, a lifesaver. I manipulated an old CMake from another project that was set up completely different; and it clearly didn't work. So it doesn't matter where you link a library or add an executable, just as long as it exists?
  • Jiří Pospíšil
    Jiří Pospíšil over 9 years
    I'm not sure what you mean. When you use functions like add_executable / add_library / ... you create a target. You can depend on this target in other targets which get created after or before the particular target. CMake will make sure all of the dependencies are met at the end and will scream otherwise.