1. Overview

While building an executable using make, we may sometimes get a “Clock skew detected” warning.

In this tutorial, we’ll see an example of this warning. Then, we’ll discuss how to solve it.

2. Examination of the Problem

We’ll examine the problem using an example.

2.1. Code Example

We’ll use the C program, hello_world.c, to analyze the problem:

#include <stdio.h>

int main()
{
    printf("Hello World\n");

    return 0;
}

The program just prints Hello World and exits.

We’ll use the following Makefile to build the program:

.PHONY: all
all: hello_world

hello_world: hello_world.c
	@gcc hello_world –o hello_world

.PHONY: clean
clean:
	@rm –f hello_world

Now, let’s build the program using make:

$ pwd
/home/alice/hello_world_project
$ ls
hello_world.c Makefile
$ make
$ ls
hello_world hello_world.c Makefile

We built the executable, hello_world, successfully. Let’s run the program:

$ ./hello_world
Hello World

The program runs as expected.

2.2. Creation of the Problem

Now, we’ll try to obtain the “Clock skew detected” warning. However, let’s first check the modification time of hello_world:

$ ls –l hello_world
-rwxr-xr-x 1 alice alice 17536 Jan 17 08:02 hello_world
$ date
Tue Jan 17 08:02:43 +03 2023

We’ll change the modification time of hello_world using the touch command:

$ touch –t 202401010000 hello_world 
$ ls –l hello_world
-rwxr-xr-x 1 alice alice 17536 Jan  1  2024 hello_world

The -t option of touch sets the modification time of a file to the specified time. We set the modification time of hello_world to a time in the future.

Let’s also update hello_world.c:

#include <stdio.h>

int main()
{
    printf("Hello World\n");
    printf("Hello World again\n");

    return 0;
}

We just added the printf(“Hello World again\n”) statement.

Now, let’s build the program once more using make:

$ make
make: Warning: 'hello_world' has modification 30123485 s in the future
make: Nothing to be done for 'all'
make: warning:  Clock skew detected.  Your build may be incomplete.

We got the “Clock skew detected” warning.

2.3. Analysis of the Problem

While performing an incremental build, make first checks the modification times of source files. If the modification time of a source file is more recent than the previously built executable using the source file, make rebuilds the executable.

However, this is the opposite in our case. The modification time of the previously built executable, hello_world, is more recent than the modification time of hello_world.c. This is the reason for getting the warning.

Let’s run hello_world once more:

$ ./hello_world
Hello World

As the output of running hello_world shows, we couldn’t even build the updated code – we don’t see Hello World again in the output.

Therefore, when we have the “Clock skew detected” warning, the source code may not even be built. It may also cause unnecessary builds.

3. Solution

Making a clean build solves the problem since the clean rule in the Makefile removes the executable using rm –f hello_world:

$ make clean 
$ make
$ ls –l hello_world
-rwxr-xr-x 1 alice alice 17536 Jan 17 08:13 hello_world

We cleaned the executable using make clean. Then, we rebuilt it using make. The modification time of the executable, hello_world, was updated as expected.

Clean build of a big project that has hundreds of source files may take a long time. Therefore, manually removing only the executable that causes the warning might be useful for having an incremental build.

However, the main reason for getting the warning is the time difference between machines. For example, we might be working in an NFS (Network File System) mounted directory, and the clocks on the NFS server and the client may not be synchronized. We tried to simulate this situation by changing modification time of the built executable. Therefore, the real solution of the problem is the time synchronization of the machines using a protocol like NTP (Network Time Protocol).

4. Conclusion

In this article, we discussed the “Clock skew detected” warning that we may come across while building an executable with make.

First, we saw an example to understand the problem. The reason for the problem was the more recent modification time of the executable than the source file’s modification time.

Then, we discussed how to avoid the problem. We saw that making a clean build solves it. It’s also possible to have an incremental build by just removing the executable with the modification time in the future.

Finally, we learned that the real solution is synchronizing the system times of the machines using a protocol like NTP.

Comments are closed on this article!