76

I'm trying to set up a test project looking like my own project just to get things working first and it looks like this:

/MainProject/inc/main.h
/MainProject/src/main.cpp
/LibProject/inc/test.h
/LibProject/src/test.cpp

I've found some tutorials, but I cant find out how to set up this when I have the inc and src folder? How would the CMakeLists.txt files look? Would I have one in /, one in each of the project folders? It seems like I dont need to have one in the inc and src folders?

Bert
  • 80,741
  • 17
  • 199
  • 164
bitgregor
  • 1,085
  • 2
  • 14
  • 17

3 Answers3

149

You need a CMakeLists.txt for each source subdirectory. Your structure should look something like this:

root
|-MainProject
| |-inc
| | '-main.h
| |-src
| | |-main.cpp
| | '-CMakeLists.txt
| '-CMakeLists.txt 
|-LibProject
| |-inc
| | '-test.h
| |-src
| | |-test.cpp
| | '-CMakeLists.txt
| '-CMakeLists.txt
'-CMakeLists.txt

Content of root/CMakeLists.txt:

project(MyProject)
add_subdirectory(MainProject)
add_subdirectory(LibProject)

Content of LibProject/CMakeLists.txt and MainProject/CMakeLists.txt:

add_subdirectory(src)

Content of LibProject/src/CMakeLists.txt:

# Notice name prefix of this variable, set by CMake according
# to value given with "project()" in the root CMakeLists.txt.
include_directories(${MyProject_SOURCE_DIR}/LibProject/inc)
add_library(LibProject test.cpp)

Content of MainProject/src/CMakeLists.txt:

include_directories(${MyProject_SOURCE_DIR}/MainProject/inc)
# I assume you want to use LibProject as a library in MainProject.
include_directories(${MyProject_SOURCE_DIR}/LibProject/inc)
link_directories(${MyProject_SOURCE_DIR}/LibProject/src)
add_executable(MainProject main.cpp)
target_link_libraries(MainProject LibProject)

Then configure and build with:

$ cd root
$ mkdir build
$ cd build
$ cmake ..
$ make
flatline
  • 42,083
  • 4
  • 31
  • 38
Good Night Nerd Pride
  • 8,245
  • 4
  • 49
  • 65
  • 13
    The point wasn't to copy your answer but rather to complete it. As far as I know it wouldn't work without the two missing `CMakeLists.txt`'s and the missing `link_directories()` command. I orignially intended to comment your answer, but my reputation is too low to do that. So I figured posting a 2nd answer would be the most self-containing way. Didn't mean to offend you. – Good Night Nerd Pride Nov 29 '11 at 01:57
  • It must work without link_directories as it's library built by the same project. As for path problem you are right, I'll correct it. – Roman Byshko Nov 29 '11 at 01:59
  • @user912403: So does that mean your question is solved? Then accept one of the two answers, by clicking on the check mark left to it. I would recommend Roman's one, since it's more concise. If you pick mine please verify whether the `link_directories` command in `MainProject/src/CMakeLists.txt` is really necessary, so I can edit the answer accordingly. – Good Night Nerd Pride Nov 29 '11 at 14:03
  • I needed the CMakeLists.txt in the MainProject and LibProject folders aswell as in the src folders.. but subdir() didn't work.. it had to be subdirs() – bitgregor Nov 29 '11 at 16:16
  • 1
    Where is MyProject_SOURCE_DIR set? – RKum Aug 25 '20 at 11:32
32

You could do it in the following way:

  • CMakeLists.txt in your MainProject directory:

    project(MainProject)
    
    add_subdirectory(LibProject/src)
    add_subdirectory(MainProject/src)
    
  • CMakeLists.txt in your LibProject/src directory:

    include_directories(${PROJECT_SOURCE_DIR}/LibProject/inc/)
    add_library(LibProject test.cpp)
    
  • CMakeLists.txt in your MainProject/src directory:

    include_directories(${PROJECT_SOURCE_DIR}/MainProject/inc/)
    add_executable(MainProject main.cpp)
    target_link_libraries(MainProject LibProject)
    
Ry-
  • 218,210
  • 55
  • 464
  • 476
Roman Byshko
  • 8,591
  • 7
  • 35
  • 57
27

In my case I wanted to do it with a single CMakeList. And it worked for me. I add my solution in case it serves to anyone.

This is what I did in my case:

My structure:
Project
|CMakeLists.txt
|-src
| |*.cpp
| |*.c
|-include
| |*.hpp
| |*.h

My CMakeLists.txt have to main parts:

include_directories(
        ${PROJECT_SOURCE_DIR}/include
        ${PROJECT_SOURCE_DIR}/src
)

^ Enables .cpp files to add headers in the include folder.

file(GLOB all_SRCS
        "${PROJECT_SOURCE_DIR}/include/*.h"
        "${PROJECT_SOURCE_DIR}/include/*.hpp"
        "${PROJECT_SOURCE_DIR}/src/*.cpp"
        "${PROJECT_SOURCE_DIR}/src/*.c"
        )

^ Just add whatever is in those folders.

add_executable(MyTarget ${all_SRCS})

^ Build the target from the list of all sources

PS: if you want to see the full CMakeLists.txt go the the project link NEGU93/ForbiddenDesert.

J Agustin Barrachina
  • 3,501
  • 1
  • 32
  • 52
  • 2
    Yes, this will produce a Makefile that will properly recompile the appropriate files if the header files change. I'm not sure the previous suggestions do that (or they don't show it explicitly, at least) – gerardw Jan 18 '19 at 15:27