3

I am trying to generate and update Qt translation files, using CMake. My problem is that when I invoke make clean, my .ts file gets removed.

I can reproduce the problem easily. Here is the CMakeLists.txt:

cmake_minimum_required(VERSION 3.7)

find_package(Qt5LinguistTools)

add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/tr.ts
  COMMAND ${Qt5_LUPDATE_EXECUTABLE} -target-language en main.cpp -ts tr.ts
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  DEPENDS main.cpp
)

add_custom_target(foo DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tr.ts)

And the translation file tr.ts:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="en">
<context>
    <name>QObject</name>
    <message>
        <location filename="main.cpp" line="8"/>
        <source>%_foo</source>
        <translation>Foo</translation>
    </message>
</context>
</TS>

My source file main.cpp:

#include <QCoreApplication>
#include <QString>

#include <iostream>

int main(int argc, char* argv[])
{
  QCoreApplication app(argc, argv);

  QString what(QObject::tr("%_foo"));
  std::cout << what.toStdString() << std::endl;
  return app.exec();
}

Simply configure the build directory and invoke the clean target:

mkdir build && cd build
cmake ..
make clean

I thought about copying the translation file in the build directory and work on this copy, but this means that any new translation found in the sources will be put in the copy, but not the initial file. I would have to copy the copy in the source directory manually.

This solution says to call set_directory_properties(PROPERTIES CLEAN_NO_CUSTOM 1), which works, but only for Makefile generators. Also, the file is not present in the property ADDITIONAL_MAKE_CLEAN_FILES.

How come the file gets removed in the first and how can I avoid this behavior without disabling cleaning custom files?

Thanks,

Community
  • 1
  • 1
piwi
  • 5,136
  • 2
  • 24
  • 48
  • 1
    Try moving `COMMAND` from `add_custom_command` to `add_custom_target` and getting rid of `add_custom_command` altogether. – arrowd Jan 10 '18 at 14:22
  • @arrowd It works, thanks for the suggestion. I'll check if I can have a single target for all my translations, because I would like to avoid having one target per translation file. – piwi Jan 10 '18 at 14:34

2 Answers2

4

You may want to simply add a custom target and explicitly invoke its build:

cmake_minimum_required(VERSION 3.7)

find_package(Qt5LinguistTools)

add_custom_target(foo COMMAND ${Qt5_LUPDATE_EXECUTABLE} -target-language en ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp -ts tr.ts)

So to build the ts file:

make foo

Any subsequent make clean calls will not affect the ts file at all. You can eventually add another target to explicitly cleanup the ts file:

add_custom_target(foo-clean COMMAND rm tr.ts)
p-a-o-l-o
  • 9,807
  • 2
  • 22
  • 35
3

CMake cleans your file, because it is marked as OUTPUT of a custom command. Make custom target produce that file, and CMake would never know about it, thus leaving it as it is during make clean. You can also specify many COMMAND bla bla arguments when calling add_custom_target to produce many files.

arrowd
  • 33,231
  • 8
  • 79
  • 110