My project is quite simple but I like to keep files in different folders for clarity. For instance I have three folders.
- An
Output
folder that contains all the classes used for the output. (for now only Output.cc and Output.h). - A
Math
folder, containing all of the classes related to math. (vector.cc, vector.h, randomgen.h, randomgen.cc, etc) - A
Tests
folder where there are different cpp files each containing a main function. (Output_test.cc, vector_test.cc, etc)
How can I create a CMake script that complies all of the different main function of the different test programs using the classes that are in different folders? In addition, I didn't see where the compiler, and its options, are specified in a CMake file.
How to specify the compiler?
There are a few ways to specify the compiler you want to use. Settings environment variables, defining compiler variables, or designating a generator.
Settings Environment Variables
There are two ways to use environment variables to help CMake determine which compiler to use during a CMake configuration. Using the
PATH
variable or theCC
andCXX
variables.PATH
Make sure the path to your desired compiler is first in the list. If you don't want to modify your path, then use the 2nd option.
CC & CXX
CMake reads the variables
CC
andCXX
to determine the path for the C compiler and C++ compiler respectively. Note that the first time CMake is configured for a project it will cache these paths, and look to the cache first for all future configurations. So if you wish to change the compiler path, be sure to delete the cache fileCMakeCache.txt
. As HughB pointed out, there is a good example of this given by GuillaumeDefining Compiler Variables
Similar to using CC and CXX, there are CMake variables that can be defined at the commandline to choose the desired compiler. They are
CMAKE_C_COMPILER
andCMAKE_CXX_COMPILER
. You can set them using the-D
option and they use the same values as CC and CXX. Note, just like CC and CXX these are cached after the first CMake configuration.Example
Designating a Generator
The last way to choose the compiler is by using the -G option to select a generator. There are numerous generators to choose and I recently answered a question about them. I'm not going to go into too much detail about them in this answer, but you can read my other answer for more details.
Example
Don't Hardcode the Compiler
I recommend resisting the urge to "hardcode" the compiler in the CMakeLists.txt files. CMake is meant to be compiler independent and you should be setting the compiler information external of the CMake files. Use one of the methods mentioned above to keep your CMake files portable and to avoid confusion if yourself or someone else wants to build the project with a different compiler.
Related references. (Disclaimer: Written by me)
How to Compile Multiple Executables?
As HughB mentioned use
add_executables
. You could also create separate libraries for each folder group, there are many ways to organize your project. I'm going to keep it simple and give an example that builds two executables in the same project.For this example I created 5 files:
include/Helloworld.h
src/HelloWorld.cpp
include/HelloWorld2.h
src/HelloWorld2.cpp
CMakeLists.txt
When this project is built there will be two executables: HelloWorld.exe and HelloWorld2.exe.
Consider putting the code that will be used in different program mains in a library. Use the add_library command to do make a library. You could have a directory hierarchy like this:
Use add_subdirectory in your top level cmakelists.txt to traverse the directories. In the dirs that build executables, use add_executable and target_link_libraries. If you named the library MyLib then your target_link_libraries command would look like
In regard to overriding the compiler, see how to specify new gcc path for cmake