Alex
Alex

Reputation: 15353

How to get a relative path to a target with CMake?

I have a project that uses CMake to generate build scripts, and each platform puts the executable that are generated in a different place. We have a non-programmer on our team who does not have build tools and I want to be able to bundle up all the files, scripts and executables necessary to run the project so that he can run the project.

To do that, I've added a custom target that takes all the necessary files and zips them up. It also generates a very simple script (which is included in the zip file) that he can just click on that should run a script then launch the executable, like so:

add_custom_target(runcommand
  COMMAND echo '\#!/bin/bash -eu' > run.command &&
          echo 'cd `dirname $$0`' >> run.command &&
          echo './scripts/prerun_script.sh && ${MY_EXECUTABLE}' >> run.command &&
          chmod +x run.command)

The problem with this is that MY_EXECUTABLE is a hardcoded path to the executable on my system. I would like it to be a relative path so that I can just take this resultant zip file, unzip it anywhere and run it from there. What I would like is to get the path to MY_EXECUTABLE relative to the root directory of my project so that this script can be run from anywhere.

Upvotes: 14

Views: 23204

Answers (4)

Role
Role

Reputation: 86

get the relative path to the current source directory

file(RELATIVE_PATH relative ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})

Test:

message(STATUS "source base: \"${CMAKE_SOURCE_DIR}\"")
message(STATUS "current: \"${CMAKE_CURRENT_SOURCE_DIR}\"")
message(STATUS "relative: \"${relative}\"")

Result:

--source base: "C:/Project/Software/Test/source"
--current: "C:/Project/Software/Test/source/unittest/libs/fsm
--relative: "unittest/libs/fsm"

Upvotes: 1

Lindydancer
Lindydancer

Reputation: 26164

You can use:

file(RELATIVE_PATH variable directory file)

Concretely, assume that MY_ROOT contains the root directory (there might be a suitable predefined CMake variable for this), this will set rel to the relative path of MY_EXECUTABLE:

file(RELATIVE_PATH rel ${MY_ROOT} ${MY_EXECUTABLE})

Upvotes: 21

Innokentiy Alaytsev
Innokentiy Alaytsev

Reputation: 840

In case where you want to get path relative to project root, you may use PROJECT_SOURCE_DIR CMake variable:

file(RELATIVE_PATH rel ${PROJECT_SOURCE_DIR} ${MY_EXECUTABLE})

Remember, that MY_EXECUTABLE must contain full path to file.

Upvotes: 3

zerodiff
zerodiff

Reputation: 1700

Something like this would work:

THISDIR=`pwd`
MY_EXECUTABLE=$THISDIR/test/someexec
REL_EXECUTABLE=${MY_EXECUTABLE##$THISDIR/}
echo $REL_EXECUTABLE 

Basically, this chops off the base path from $MY_EXECUTABLE. In this example, I just set up MY_EXECUTABLE as a test to give it a full path. The one-line equivalent for what you want is:

${MY_EXECUTABLE##`pwd`/}

I guess this assumes pwd is the root of your project. Otherwise, see the Cmake variable doc.

(As an aside, this makes me nostalgic for the ksh days.)

Upvotes: -2

Related Questions