The CMake code in interfaces/CMakeLists.txt also showed that it is possible to create a library from source files in different languages. CMake is evidently able to do the following:
- Discern which compiler to use to get object files from the listed source files.
- Select the linker appropriately to build a library (or executable) from these object files.
How does CMake determine which compiler to use? Specifying the LANGUAGES option to the project command will let CMake check for working compilers for the given languages on your system. When a target is added with lists of source files, CMake will appropriately determine the compiler based on the file extension. Hence, files terminating with .c will be compiled to object files using the C compiler already determined, whereas files terminating with .f90 (or .F90 if they need preprocessing) will be compiled using the working Fortran compiler. Similarly for C++, the .cpp or .cxx extensions will trigger usage of the C++ compiler. We have only listed some of the possible, valid file extensions for the C, C++, and Fortran languages, but CMake can recognize many more. What if the file extensions in your project are, for any reason, not among the ones that are recognized? The LANGUAGE source file property can be used to tell CMake which compiler to use on specific source files, like so:
set_source_files_properties(my_source_file.axx
PROPERTIES
LANGUAGE CXX
)
Finally, what about the linker? How does CMake determine the linker language for targets? For targets that do not mix programming languages, the choice is straightforward: invoke the linker via the compiler command that was used to generate the object files. If the targets do mix programming languages, as in our example, the linker language is chosen based on that whose preference value is highest among the ones available in the language mix. With our example mixing Fortran and C, the Fortran language has higher preference than the C language and is hence used as linker language. When mixing Fortran and C++, it is the latter to have higher preference and is hence used as the linker language. Much as with the compiler language, we can force CMake to use a specific linker language for our target via the corresponding LINKER_LANGUAGE property on targets:
set_target_properties(my_target
PROPERTIES
LINKER_LANGUAGE Fortran
)