How get get the path of the installed executable?

On Linux for item Exec of .desktop, it needs the path of the executable?
Is there any better way than manully constructing as below?

set(Item_Exec ${CMAKE_INSTALL_FULL_BINDIR}>/<target_name>)

You can use file(GENERATE ...) and use a generator expression.

file(GENERATE ...) generates a file, but I want to save it to a variable instead.

You won’t be able to save it to a variable, because the output path is not known until generate-time, after CMakeLists.txt has already been processed.

So the best way is

set(Item_Exec ${CMAKE_INSTALL_FULL_BINDIR}>/<target_name>)


In general you can’t deduce the install location of binaries/libraries from CMake. As Kyle mentioned above that variable could hold generator expressions which have to be evaluated after CMake script execution to resolve to a valid path. In addition the cmake --install command offers the --prefix flag that allows changing the install location without re-executing CMake.

Under certain conditions ( GNUInstallDirs being used ) your solution might be sufficient, but it won’t be robust.

As far as .desktop files are considered ( Desktop Entry Specification ) you can just provide the name of the executable and allow the OS to search the environments PATH variable to find the program.

1 Like

But the executable is in /opt/myapp/bin/, the default environment variable PATH doesn’t help.

I don’t have enough information to be definitive here, but one of two scenarios seems likely.

Scenario: You have standards or control over the destination system

In that case, maybe you just hardcode /opt/myapp/bin/ into *.desktop files in your package and move on.

Scenario: You have inconsistent or incomplete information about how the package is installed

Have you considered using a template file instead of a proper *.desktop file and use your packaging systems package-install-time hooks to generate (via sed perhaps?) a *.desktop file that knows the actual path as installed on the actual system? As stated above, CMake doesn’t actually know about even /opt/myapp necessarily. Many packaging systems don’t even manipulate a directory like /opt/myapp when CMake is in the picture, instead they install into a staging directory and then package that up. To be sure you’d know about the /opt/myapp path, you might need to inject that info into your *.desktop file much later in the process… for instance when the actual package installation is in progress.