cmake: build depends on none-source files. Qt help generation - c++

I'm trying to generate Qt help files during build.
.qhp (Qt help project), contains list of HTML files located in /html folder adjacent to .qhp file.
It works fine, if I change .qhp file. But if I change only HTML files the build is not started.
This is part of my CMakeLists.txt:
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/help.qch
COMMAND qhelpgenerator ${CMAKE_CURRENT_SOURCE_DIR}/help.qhp -o ${CMAKE_CURRENT_BINARY_DIR}/help.qch
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/help.qhp
)
ADD_CUSTOM_TARGET(${TARGET_NAME}
ALL DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/help.qch
SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/uav_help.qhp
)
Q: How can I add dependencies to HTML files (w/o creating list of them in CMakeLists.txt), if I don't want to add them to the project?
Q2: Are there other ways to organize automatic .qch generation during build?

List these HTML's in DEPENDS of add_custom_command() call too, obviously.
You can also look at KDE's Extra CMake Modules project, which contains ECMAddQch macro.

Related

Custom CMake target that uses only CMake functions [duplicate]

I have a project under CMake with some files generated with python generator from XML files. I cannot specify all files generated by this generator in CMakeLists.txt so I use file globbing for this.
The problem is that when I update my XML files or generator sources (which are in the same repository) I would like to have my build system reconfigured so changed files are taken into account when rebuilding the code (via make for example).
Is it possible to make CMake treat some files like it treats CMakeLists.txt files and to make it regenerate build system when those file are changed?
It doesn't require any kind of workarounds. The standard way is to use CMAKE_CONFIGURE_DEPENDS property:
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS <filename>)
Yes, you should be able to do that by (ab)using configure_file(). Configuring a file makes the source a dependency of the CMake run, so that any changes in it cause a reconfiguration. Simply like this:
configure_file(MyInputFile.xml DummyOutput.xml)
Since it has been a while I will add to #roolebo's answer.
There's actually a better command to add a dependency on a file:
set_directory_properties(PROPERTIES CMAKE_CONFIGURE_DEPENDS <relative_or_full_path_to_file>)
What might be confusing is that this command adds a property to the current directory. Well, it does not matter since you can set a full path to a file that resides outside of the current directory's scope, for instance: ../../config.json

Cmake project with multiple directories and multiple CMakeLists

I have been given some C++ source files, together with a CMakeLists.txt file, which compile to create an executable. I now want to add my own source files to this project. However, I want to keep the original source files, and the original CMakeLists file, separate from the new files.
So, I want my solution to look like this:
/Project
/Project/src
/Project/src/CMakeLists.txt
/Project/src/OriginalSource
/Project/src/OriginalSource/CMakeLists.txt
/Project/src/OriginalSource/Original.cpp
/Project/src/NewSource
/Project/src/NewSource/CMakeLists.txt
/Project/src/NewSource/New.cpp
/Project/build
I want all the source files to then compile into an executable to be placed in the build directory. So my question is, what do I put in the three CMakeLists files, such that src/OriginalSource/CMakeLists.txt just compiles the original sources, src/NewSource/CMakeLists.txt just compiles the new sources, and src/CMakeLists.txt links together all these built sources, and creates an executable?
You could create a convenience library out of your code and then link it to the code you've already got. The idea is explained here.
Please see this link for more details:
http://www.cmake.org/Wiki/CMake/Tutorials/Object_Library
I hope it helps.
No way to change the executable project in OriginSource without modifying the CMakeLists.txt in it. If you really do not want to modify the original project, you could write a new CMakeLists.txt including old and new sources.
One trick is define new sources in /Project/src/CMakeLists.txt, then include them in /Project/src/OriginalSource/CMakeLists.txt:
set(NEW_INCS ${CMAKE_SOURCE_DIR)/NewSource)
file(GLOB NEW_SRCS ${CMAKE_SOURCE_DIR)/NewSource/*.cpp)

How to remove tokens from a list in cmake?

I want to exclude some source files from building when not in Windows.
What is wrong in the following CMakeLists.txt cmake file?
aux_source_directory(. SRC_LIST)
# Remove Microsoft specific files
message(${SRC_LIST})
list(REMOVE_ITEM SRC_LIST stdafx.h stdafx.cpp)
message("------------------")
message(${SRC_LIST})
The contents of the messages before and after trying to remove the two files are exactly the same.
What is wrong?
You have to specify the exact name of the element you want to remove.
In your case, aux_source_directory prepends each entry with a ./, so the correct command has to be
list(REMOVE_ITEM SRC_LIST ./stdafx.h ./stdafx.cpp)
Also, please make sure you understand the implications of using manual calls to aux_source_directory for maintaining lists of source files:
It is tempting to use this command to avoid writing the list of source
files for a library or executable target. While this seems to work,
there is no way for CMake to generate a build system that knows when a
new source file has been added. Normally the generated build system
knows when it needs to rerun CMake because the CMakeLists.txt file is
modified to add a new source. When the source is just added to the
directory without modifying this file, one would have to manually
rerun CMake to generate a build system incorporating the new file.
Quoting the documentation for aux_source_directory.

cmake: read and compile dynamically-generated list of cpp files

I have a custom tool that processes a given list of IDL files and produces a number of .cpp and .h files as output. I want to add those files to the list of things to compile in my CMakeLists, and also model the dependencies those files have on the IDL.
To keep things simple, I will state that any change to any of the IDL files should trigger a regeneration of all cpp/h.
I have a custom command that takes care of running the generator tool and listing all the IDL files as dependencies.
My issue is getting the subsequent list of cpp/h files into cmake at build-time. It is not possible to infer from the name of the IDL files what cpp files will be generated. My generator tool will, however, output the list of generated files to a text file.
So my question is: how do I instruct cmake to "read from this text file and add the contents as extra source and header files to be compiled", also bearing in mind that the said text file only exists during a certain point of the build?
CMake needs to be able to infer the names of all .cpp files participating in the build at configure time. It is not possible to add files afterwards without re-running CMake.
One possible approach would be to use a two-phase CMake build: Instead of building the generated source files directly from your main project, you create a separate CMake project for building just the generated sources.
Then in your main CMake project you add a custom target that runs after the code generation and invokes CMake to both configure and build the generated files project.
The disadvantage here is that the generated files no longer appear as part of the main project. Also some trickery is required if you don't want to rebuild the generated sources every time - custom targets are always considered out-of-date, so you might want to use a script here that only runs CMake on the subproject if the generated files changed.
This is a few years late but this works just fine:
#run whatever tool that generates the cpp files
execute_process(COMMAND "./your_tool.sh")
#read files from files.txt and make a cmake 'list' out of them
file(READ "files.txt" SOURCES)
#found this technique to build the cmake list here:
#http://public.kitware.com/pipermail/cmake/2007-May/014236.html
#maybe there is a better way...
STRING(REGEX REPLACE ";" "\\\\;" SOURCES "${SOURCES}")
STRING(REGEX REPLACE "\n" ";" SOURCES "${SOURCES}")
#at this point you have your source files inside ${SOURCES}
#build a static library...?
add_library(mylib STATIC ${SOURCES})
There is a function that build the list directly from file:
file(STRINGS <filename> <variable> [<options>...])
source: https://cmake.org/cmake/help/v3.11/command/file.html

How to integrate QT internationalization to CMake?

Greetings all,
I am trying to use QT internationalization with CMake.
I have configured my cmake file as follows :
#Internalization - this should generate core_jp.ts ?
SET(rinzo_core_TRANSLATIONS
i18n/core_jp.ts
)
#these are my source files in the project
SET(FILES_TO_TRANSLATE
${rinzo_core_srcs}
${rinzo_core_moh_srcs}
)
QT4_CREATE_TRANSLATION(QM_FILES ${FILES_TO_TRANSLATE} ${rinzo_core_TRANSLATIONS})
QT4_ADD_TRANSLATION(QM ${rinzo_core_TRANSLATIONS})
But it doesnt genereate any TS nor QM files.
My questions -
1.Does Cmake(by using QT tools) generate TS files automatically extracting "tr()" methods from the source ? (that means I dont have to create any TS file and above i18n/core_jp.ts will be genereated automatically)
2.What exacly are QM files ?
Thanks in advance
In CMake documentation see QT4_CREATE_TRANSLATION and QT4_ADD_TRANSLATION macros.
So you should do the followings:
SET(Lang_files
example.ts
)
...
QT4_CREATE_TRANSLATION(LangSrcs ${Lang_files})
...
ADD_EXECUTABLE(project_name ... others sources ... ${LangSrcs})
Translation binary files (*.qm) according to http://itk.org/Wiki/CMake:How_To_Build_Qt4_Software
Also from the bottom of that website
Usage - Updating the .ts files
When you want it to process all your
source files (looking for new texts to
translate), configure cmake to turn on
UPDATE_TRANSLATIONS, and then make
your project. CMake will modify your
.ts files in your SOURCE folders in
addition to generating the .qm files.
WARNING: Be aware that CMake will be updating the source .ts files, which means that if > you do a make clean, it will DELETE your source .ts files!!! So it would be a good idea > to switch off UPDATE_TRANSLATIONS as soon as possible.
My solution relies on manually invoked lupdate and lrelease tools via add_custom_target, so the generated files are not removed on make clean and put into the source directory.
I defined a function that scans provided directory, generates/updates ts files, and compiles them into qm files in the same directory, so they can be added to the app via .qrc file
cmake_minimum_required(VERSION 3.5)
project(l10n LANGUAGES CXX)
find_package(Qt5 COMPONENTS Core LinguistTools REQUIRED)
# genearats ts and qm file searching recursively SRC_DIR
function(generate_translations CUSTOM_TARGET TS_DIR TS_FILES SRC_DIR)
set(UPADTE_TS_TARGET_NAME ${CUSTOM_TARGET}_ts)
set(UPADTE_QM_TARGET_NAME ${CUSTOM_TARGET}_qm)
add_custom_target(${UPADTE_TS_TARGET_NAME}
COMMAND ${Qt5_LUPDATE_EXECUTABLE} -recursive ${SRC_DIR} -ts ${TS_FILES}
WORKING_DIRECTORY ${TS_DIR})
add_custom_target(${UPADTE_QM_TARGET_NAME}
COMMAND ${Qt5_LRELEASE_EXECUTABLE} ${TS_FILES}
WORKING_DIRECTORY ${TS_DIR})
add_dependencies(${UPADTE_QM_TARGET_NAME} ${UPADTE_TS_TARGET_NAME} )
add_dependencies(${CUSTOM_TARGET} ${UPADTE_QM_TARGET_NAME})
endfunction()
add_executable(l10n main.cxx)
target_link_libraries(l10n Qt5::Core)
set(MY_TS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/translate)
set(MY_TS_FILES foo_en.ts foo_en.ts)
set(MY_SOURCE_LOOKUP_DIR ${CMAKE_CURRENT_SOURCE_DIR})
generate_translations(l10n "${MY_TS_DIR}" "${MY_TS_FILES}" "${MY_SOURCE_LOOKUP_DIR}")
can you use lupdate.exe, linguist.exe and lrelease.exe from qt/[qt_version]/[msvc|mingw|...]/bin/ ?
you can use it like that:
Usage:
lupdate [options] [project-file]
lupdate [options] [source-file|path]... -ts ts-files
Options:
-help Display this information and exit.
-noobsolete
Drop all obsolete strings.
-extensions [,]...
Process files with the given extensions only.
The extension list must be separated with commas, not with whitespace.
Default: 'ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx'.
-pluralonly
Only include plural form messages.
-silent
Do not explain what is being done.
-version
Display the version of lupdate and exit
so, [source-file|path] - is you option, like i think.
try to call it with list of source files names.