21
votes

I'm developing a C++ project which is going to be enclosed on a bigger one.

I've seen that on the bigger project (is a Qt application and it's being generated from qmake) I am able to compile a single file from the linux command line, just entering the relative path to the specific file as an argument to make.

On the other hand, I'm using CMake for my own project. When I modify some code for a compilation unit and I have to modify its header file, I have to wait a long time to compile its dependencies and then its own source file. But there are some situations in which I would prefer to check whether the source code in the *.cc file is compilable without errors.

Is there a way to generate a Makefile from CMake the way qmake does this? Switching to qmake is not an option anymore.

6
Try make help on your current CMake-generated makefile. I'm pretty sure that will list how to build just a single object file.John

6 Answers

28
votes

You do not have to add extra custom targets to your CMake scripts, as the Makefiles generated by CMake already contain .o targets for each .cc file. E.g. if you have a source file called mySourceFile.cc, there will be a Makefile in your build directory that defines a target called <Some Path>/mySourceFile.cc.o. If you cd into your build directory, you can use grep or ack-grep to locate the Makefile that defines this target, then cd into that Makefile's directory and build it.

E.g. suppose the command ack-grep mySourceFile.cc.o prints something like:

foo/bar/Makefile
119:x/y/z/mySourceFile.o: x/y/z/mySourceFile.cc.o
123:x/y/z/mySourceFile.cc.o:
124:    # recipe for building target

Then you can build mySourceFile.cc.o by doing:

cd foo/bar && make x/y/z/mySourceFile.cc.o
18
votes

CMake doesn't have a generic built-in way of doing this (it's an open issue), but if you're using the Ninja generator, you can can use a special Ninja syntax for building just the direct outputs of a given source file. For example, to compile just foo.o you would use:

ninja /path/to/foo.cpp^
7
votes

Not out-of-the box. CMake does not expose those "internal" makefile rules in the main makefile.

You can do this only if you consider what kind of file structure CMake uses internally. You can e.g. for compiling a single .obj files using CMake generated makefiles call

make -f CMakeFiles/myProg.dir/build.make CMakeFiles/myProg.dir/main.cc.obj

when you have something like

cmake_minimum_required(VERSION 3.1)

project(myProg CXX)

file(WRITE "main.cc" "int main()\n{\nreturn 0;\n}") 
add_executable(myProg main.cc)
5
votes

To build src/foo.cpp alone:

cmake --build . --target src/foo.cpp.o
1
votes

Others have suggested ways to find the target name (ending in .cpp.o) from the .cpp filename, but if you already know the name of a target that will trigger compilation of the .cpp file and you're using ninja this suggestion should be easier.

First build the target:

ninja TriggersCppCompilationLib

Assuming your file was changed or was not yet built, ninja will print the full target name. When you see the name come up, hit enter so it is not overwritten. Then simply copy the name from the terminal (e.g. using tmux copy mode).

0
votes

No, CMake does not offer built-in support to compile single files.

You have to add a target for each object file, maybe by a function iterating over all files of a directory.