1

I'm trying to get a Rust hello world to build as part of a much larger catkin/cmake build. The relevant part of the relevant CMakeLists.txt file is:

add_custom_target(_rtde_interface ALL)
set(CARGO_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command( TARGET _rtde_interface
                    PRE_BUILD
                    COMMAND cargo build
                    # WORKING_DIRECTORY ${CARGO_TARGET_DIR}/src/rtde_interface
                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/rtde_interface
                    VERBATIM)

But Cargo is behaving as if the CARGO_TARGET_DIR variable is unset. If I set it in the shell before invoking Catkin the binary shows up in whatever directory I choose, and if I leave it unset in the shell it defaults to ${CMAKE_CURRENT_SOURCE_DIR}/src/rtde_interface/target/, but the build results never get put in ${CMAKE_CURRENT_BINARY_DIR}, and I don't know why. I have used the Cmake message function to confirm that CMAKE_CURRENT_BINARY_DIR contains a real path...

Any ideas?

teryret
  • 240
  • 2
  • 11
  • I'm totally unfamiliar with rust/cargo, but familiar with CMake. I understand your question as `CARGO_TARGET_DIR` being an *enviornment* variable which the command `cargo` expects to find set in its environment. Is that the case? – Angew is no longer proud of SO Apr 04 '19 at 17:15
  • TBH I don't understand the distinction between a variable set in an environment and an evironment variable. https://doc.rust-lang.org/cargo/reference/environment-variables.html explains what Cargo is looking for, and I thought `set()` was the CMake way of achieving that... – teryret Apr 04 '19 at 17:18
  • @tsyvarev, This question is only a duplicate of the linked one if you happen to already know the answer. We shouldn't assume this of future readers. In this case @angew provided real insights not present in the link you provided, namely, that "CMake's set command does not set environment variables, it sets CMake variables." and his whole explanatory comment about why `set(ENV{VAR} value)` doesn't work. Edit: Just because the answer is a duplicate doesn't mean the question is. – teryret Apr 04 '19 at 21:32
  • Your question and the linked one is about setting an environment variable from CMake for the custom command/target. This is why your one is marked as a duplicate of the linked one. Whether your attempt to resolve the problem differs from the attempt in the referenced question is unrelated - you both **want the same**. Note, that on Stack Overflow the "duplicate" does **not** mean "bad" and does **not** imply immediate removing. Both questions may co-exist and receive upvotes. We just want the answers to be in the single place and we do not want to repeat that answers for every question. – Tsyvarev Apr 04 '19 at 21:54

1 Answers1

1

CMake's set command does not set environment variables, it sets CMake variables. If you need to modify the environment of a command launched at build time, you can use CMake's command-execution mode. That would look like this:

add_custom_target(_rtde_interface ALL)
add_custom_command( TARGET _rtde_interface
                    PRE_BUILD
                    COMMAND ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} cargo build
                    # WORKING_DIRECTORY ${CARGO_TARGET_DIR}/src/rtde_interface
                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/rtde_interface
                    VERBATIM)

If the commented-out bit is actually your intended functionality and just wasn't working right, you can replace it with this:

WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src/rtde_interface
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
  • Huh, the [cmake docs](https://cmake.org/cmake/help/v3.0/command/set.html) made it sound like it could set environment variables. (I even found there a mistake I had been making, but it didn't fix the issue). – teryret Apr 04 '19 at 17:35
  • 1
    @teryret You can indeed set environment variables using the special `set(ENV{VAR} value)` syntax, but this applies to the running CMake process and its child processes, if any. Builds happen long after CMake has finished running, so you cannot influence the build environment this way. When working with CMake, it's always important to keep the different stages (CMake configure, CMake generate, build) in mind. – Angew is no longer proud of SO Apr 04 '19 at 17:37