0

My project uses CMake to build both static and dynamic libraries from the same C++ code. The dynamic library file (.so) stays the same on rebuild, but the static library file (.a) changes on every rebuild. I have come to understand that it's because of the behaviour of ar tool and I need to pass D argument to create deterministic output.

I've found a cmake variable CMAKE_AR, which points to /usr/bin/ar on my machine. The compile output shows that the command executed is: /usr/bin/ar qc libfoo.a file1.o file2.o ....

From ar documentation, I should be changing the above invocation to /usr/bin/ar qcD ... for deterministic output.

How do I accomplish this with CMake?

I'm on Linux and need a solution compatible with CMake >= v3.11

Syam
  • 163
  • 1
  • 8
  • You may add your additional options to the `CMAKE_STATIC_LINKER_FLAGS` variable, e.g. `set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} D")` – vre Jun 02 '21 at 09:29
  • @vre That doesn't work. It results in: `/usr/bin/ar qc libfoo.a D file1.o file2.o ...`. – Syam Jun 02 '21 at 09:31
  • 2
    This question provides additional information and a possible solution https://stackoverflow.com/questions/62339192/how-set-cmake-static-linker-flags-immediately-after-the-executable-file-tcc-a – vre Jun 02 '21 at 09:35
  • 1
    @vre Thanks a lot for that link. Although the method in that didn't quite work, there was a link to CMake git repo that helped. `set(CMAKE_CXX_ARCHIVE_CREATE " qcD ")` seems to do the trick – Syam Jun 02 '21 at 09:56

1 Answers1

0

The following works to set arguments for ar and ranlib for generating deterministic static library output files:

set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qcD <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -D <TARGET>")
Syam
  • 163
  • 1
  • 8