How do you make _topdir relative to the location of the .spec file when building an RPM? - relative-path

I have a .spec file that relies on a variable called _topdir.
Right now when you checkout the SRPM source from git, you have to go and change where _topdir is pointing to to get the rpmbuild to function correctly.
# We need the following line so that RPM can find the BUILD and SOURCES and RPMS dirs.
%define _topdir /root/projects/my-project/my-project-srpm/
How do you specify that _topdir should be relative to the location of the .spec file so that _topdir isn't hard coded?

specify your topdir on the command line like so ...
rpmbuild --define "_topdir \`pwd\`" ...

You can define the _topdir variable in your spec file (e.g., at the top)
%define _topdir %(echo $PWD)/

In your ~/.rpmmacros file, do this:
%_topdir %(echo $PWD)/subdir
I'm unsure if you can do this inside the spec file itself, I don't see why not, but I'm unsure how to notate it.

Related

Getting environment variable during runtime from file in cmake [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

changing the project name on every build

I have a custom makefile used for versioning.
It basically sets the version according to some predefined rules and fetching info from git repo
I want to intergrate it with the esp32 cmake project.
Till now i managed to run the makefile from the cmakelist.txt file using
add_custom_target(versioning ALL
COMMAND ${CMAKE_COMMAND} -P "sometext.cmake"
)
and in the sometext.cmake i am calling the makefile which sets a FirmwareVersion variable.
I use this variable in the root cmakelist.txt to set the project(${FirmwareVersion})
But i want the project name to be changed every time firmwareVersion is changed.
But project command is only if there is some changes in cmakelist.txt
Any help to accomplish it is highly apreciated.
Thanks
The project() command also has VERSION named keyword. That is what you actually want. You can store the actual version in some extra CMake file (like version.cmake)
set(VERSION_FROM_GIT "1.2.3+9a6b075")
and use like
include("${CMAKE_CURRENT_SOURCE_DIR}/version.cmake")
project(MyProject VERSION ${VERSION_FROM_GIT} ...)
...
It's up to you how you going to update this file... There are plenty of ways to do that.
You can tell cmake to do a reconfiguration if a file changes. Since the .git directory contains a HEAD file either denoting the commit hash of the detached head or a reference to the file containing the commit hash, you could these files as configuration dependencies.
# assume the .git directory is in the same directory as this CMakeLists.txt
set(GIT_HEAD_FILE "${CMAKE_CURRENT_SOURCE_DIR}/.git/HEAD")
# add dependency to the head itself
set_property(DIRECTORY . APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${GIT_HEAD_FILE}")
file(READ "${GIT_HEAD_FILE}" GIT_HEAD_CONTENT)
if (GIT_HEAD_CONTENT MATCHES "ref: +([^ ]+)")
# add file referenced in HEAD for non detached head state
set_property(DIRECTORY . APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/.git/${CMAKE_MATCH_1}")
endif()
... your logic depending on the git version goes here ...
This gets a bit more complicated if you intend on using your repository as submodule of another repo, since the .git directory is not necessarily located in the submodule.

Cmake add_definition to compute absolute path of a file

I have a project where compilation and test running is managed by cmake. The test involves reading a special test file, which is located in different directory from the test file and would need an absolute path. I define the path to the testfile in my tests.cpp like this:
#define ARPA_TESTFILEPATH "/path/to/project/root/arpa/toy_lm.arpa"
I want to pass that define via cmake so that other people can checkout the project and run the tests without modifying anything. I know I can add defines in cmake via:
add_definitions(-DARPA_TESTFILE="/path/to/project/root/arpa/toy_lm.arpa")
However how can I add a variable to the define so that it automatically resolves the path? I am looking for something like:
add_definitions(-DARPA_TESTFILE="$(PROJECTROOT)/arpa/toy_lm.arpa")
Is that possible?
EDIT:
Basically say the project is checked out in a directory
/home/pesho/project
the project directory contains CMakeLists.txt. How could I get the absolute path to the projects directory so that I can include it in a variable and then define it during compilation.
Put the path in a CACHE variable. It make it accessible through ccmake command :
set(PATH_TO_ARPA "${DEFAULT_PATH_TO_ARPA}" CACHE FILEPATH "Description of the option")
See documentation : http://www.cmake.org/cmake/help/v3.0/command/set.html

CPack NSIS, generate installer for Windows

I´m trying to run packet generator within a VS project, it crashes while compiling because of the use of absolute path on installation from Targets and Files.
ABSOLUTE path INSTALL DESTINATION forbidden (by caller): ...
I checked twice and all installation directories are relative. I set quite a lot of variables as sub-folders of ${PROJECT_BINARY_DIR} (which should be relative) such as:
set(INSTALL_DIR ${PROJECT_BINARY_DIR}/bin)
set(LIB_DIR ${PROJECT_BINARY_DIR}/bin/lib)
set(EXT_DIR ${PROJECT_BINARY_DIR}/bin/ext)
...
does CMAKE/CPACK interpret those variables as absolute paths?
If so, is there a way to make CPack working properly with those variables?
How do I use CPack when sub-relative path are involved?
thanks
Ok I see, the ${PROJECT_BINARY_DIR} is interpreted as an ABSOLUTE path, from there all sub-folder of it will be rejected.
To avoid this problem I surrounded the install variables in if else blocks, and if it is the case of packaging then a relative folder will be used as follows:
if(PACK)
set(INSTALL_DIR bin)
set(LIB_DIR bin/lib)
set(EXT_DIR /bin/ext)
...
else(PACK)
set(INSTALL_DIR ${PROJECT_BINARY_DIR}/bin)
set(LIB_DIR ${PROJECT_BINARY_DIR}/bin/lib)
set(EXT_DIR ${PROJECT_BINARY_DIR}/bin/ext)
...
endif(PACK)
this solves it, but it is really dirty, waiting for a better function on new CPack version.
ciao
This fatal error is meant to tell you installation root should be specified at the moment when user executes the installer. I guess somewhere in your cmake config might have code like this:
INSTALL (TARGET myApp DESTINATION ${SOME_INSTALL_PATH}/bin )
If you assign SOME_INSTALL_PATH an absolute path when cmake cache is generated, you incur the CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION error, which gave you the "ABSOLUTE path INSTALL DESTINATION forbidden (by caller)" message.
To solve this problem, either always use relative path for installation DESTINATION or assign only package prefix to SOME_INSTALL_PATH variable.
For reference, following is the link to INSTALL command.
http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.html
There was also a similar question asked on the CMake mailing list.
http://public.kitware.com/pipermail/cmake/2013-May/054656.html

Add file dependencies to a custom target

I would like to set up CMake to build qresource files when the contents of files referenced in the .qrc file change. For example I have some qml files that are packaged into a qrc file and the qrc needs to be recompiled if the qml files are changed.
I have the following macro to run the resource compiler but it will only rebuild it if the resource file itself changes.
MACRO(PYQT5_WRAP_RC outfiles)
FOREACH(it ${ARGN})
GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
SET(outfile ${CMAKE_CURRENT_SOURCE_DIR}/${outfile}_rc.py)
ADD_CUSTOM_TARGET(${it} ALL
DEPENDS ${outfile}
)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${PYRCC5BINARY} ${infile} -o ${outfile}
MAIN_DEPENDENCY ${infile}
)
SET(${outfiles} ${${outfiles}} ${outfile})
ENDFOREACH(it)
ENDMACRO (PYQT5_WRAP_RC)
The macro is used like this:
PYQT5_WRAP_RC(rc_gen file1.qrc file2.qrc ...)
How can I make it so the qrc file gets recompiled if one of files that it refers to changes?
Do I need to do something convoluted like this?
It seems to me that the command you are looking for is add_custom_command:
This defines a command to generate specified OUTPUT file(s). A target
created in the same directory (CMakeLists.txt file) that specifies any
output of the custom command as a source file is given a rule to
generate the file using the command at build time.
Configuring the dependencies correctly you should be able to get the file recompiled only when it is really needed.
If I understand correctly your situation, the problem is that CMake does not know anything about what qrc file is and it does not know, that qrc file references some other files. This dependency is implicit for CMake (compare with C++ includes; but for those cmake have special mechanisms to detect dependencies).
So, as I understand, what you can do is to use add_custom_target (which is executed always) but not only add qrc file to its depends, but also write some script, which whould check that files referenced in qrc are also up to date and if they are not, then touch qrc file).
Of course you can use methods from the other answer, which you reference above, to touch qrc file, but you have to develop your own script to extract paths of files referenced in qrc files. Then you can use CMake scripting facilities to check if they are up to date and to touch qrc file.