12

I'm using cmake to build my project in C++. Assume I have the following directories on my Source folder

Source |_Dir1 | |_Class.cpp | |_Class.hpp | |_Dir2 |_Main.cpp 

In Dir1 there's a class with its header and implementation files (Class.cpp and Class.hpp).

In Dir2 there's the main application which uses the class in Dir1

What is the good way to tell the CMakeLists in Dir2 to build the executable with Dir1/Class.cpp file?

EDIT: To be more specific, I want to define that the source file for Class.cpp has to be used in Dir1's CMakeLists.txt, and not in Dir2's. Doing it the other way feels plain wrong to me and it's hard to use, so if there's a reason they're enforcing me to do this some clarification on the topic would be nice.

What I'm currently doing is hard-coding the Class.cpp file location in Dir2/CMakeLists.txt but that just doesn't scale when I've got a bunch of classes interacting together.

8
  • You can use the FILE(GLOB ...) action to gather a bunch of files with a particular extension. Commented Sep 1, 2014 at 16:18
  • But won't that work only inside of Dir2? I want to use the cpp file in Dir1. I specifically want not to have to specify all the files in the executable folder's CMakeLists but make each folder register the cpps it has. Commented Sep 1, 2014 at 16:21
  • 1
    possible duplicate of CMake - Automatically add all files in a folder to a target? Commented Sep 1, 2014 at 16:21
  • @Setzer22 You can use the RELATIVE option to specify whichever directory you want. What about looking into CMake's manual? Commented Sep 1, 2014 at 16:23
  • @πάντα ῥεῖ I'm not sure I understand what the relative function does. Are you sure that helps me in any way to define the source files for my executable from another folder? Commented Sep 1, 2014 at 16:27

1 Answer 1

25

Supposed you have a single CMakeLists.txt file at the Source directory, you'll create two variables using different file() commands

file(GLOB Dir1_Sources RELATIVE "Dir1" "*.cpp") file(GLOB Dir2_Sources RELATIVE "Dir2" "*.cpp") 

and add both sets generated by the file() commands to your target's source list:

add_executable(MyProgram ${Dir1_Sources} ${Dir2_Sources}) 

Alternatively you can place a CMakeLists.txt file under Dir1 and Dir2 (Main) looking as follows

Source | |_ CMakeLists.txt | > project(MyProgram) | > cmake_minimum_required(VERSION 3.8) | > add_subdirectory("Dir1") | > add_subdirectory("Dir2") | |_ Dir1 | |_ CMakeLists.txt | > file(GLOB Sources "*.cpp") | > add_library(Dir1 STATIC ${Sources}) |_ Dir2 |_ CMakeLists.txt > file(GLOB Sources "*.cpp") > add_executable(MyProgram ${Sources}) > target_link_libraries(MyProgram Dir1) 

to add subdirectories as further (static) libraries linked to your main target.

Sign up to request clarification or add additional context in comments.

5 Comments

What I'm asking for is the line file(GLOB Dir1_Sources RELATIVE "Dir1" "*.cpp") to be in a different CMakeLists.txt file, the one in Dir1, not Source nor Dir2. But I see that's not the workflow with CMake as everyone in the internet seems to be insisting in doing everything on a single file. Yours is a nice trick anyway, thank you.
@Setzer22 Yeah, of course this sample supposed that you have a single CMakeLists.txt at Source level. Well, though you could also place appropriate CMakeLists.txt files in the (non main) subdirectories to build libraries, and add these with add_subdirectory(), but as you mentioned that's not the usual way to just gather from sources.
@Setzer22 I've added another sample for the mentioned alternative solution.
I made a few edits to please CLion. Importantly, add_executable needs to come before target_link_libraries, otherwise cmake will complain.
Not sure why RELATIVE is used here, but line file(GLOB Dir1_Sources RELATIVE "Dir1" "*.cpp") being executed in CMakeLists.txt, doesn't collect sources in Dir1/ subdirectory. Correct call would be file(GLOB Dir1_Sources "Dir1/*.cpp").

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.