I've created a simple CMake C++ library example and I want to make its build deterministic (i.e. The same code in same machine always generates the same library with same file hash).
Main.cpp
#include <iostream>
int main()
{
std::cout << "Hello World!" << std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(Test)
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -rD <TARGET> <LINK_FLAGS> <OBJECTS>")
add_library(Test Main.cpp)
When I build this, the libTest.a file contains a timestamp which makes it non-deterministic. I've found the "D"eterministic mode of "ar" (3rd line in CMakeLists.txt) and it updates (set to 0) the timestamps of each object file in the archive but still one timestamp is remaining.
Diff:
user@ip:/x01/user/myWork/test/build>diff <(strings libTest.a) <(strings ../backup/libTest.a)
2c2
< / 1596642127 0 0 0 14 `
---
> / 1596641163 0 0 0 14 `
Of course I can edit the archive later and remove the timestamp but is there another way in CMake?
Tool versions:
ar --version
GNU ar version 2.27-41.base.el7
gcc --version
gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
cmake --version
cmake version 3.12.2
make --version
GNU Make 3.82
Built for x86_64-redhat-linux-gnu
CMAKE_CXX_ARCHIVE_FINISH worked for me.
CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
project(Test)
SET(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -crD <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> -rD <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -D <TARGET>")
add_library(Test Main.cpp)