0

I have the following in a CMakeLists.txt file. I'm trying to use cmake to check if a conda environment named myenv is installed on the system and activate that environment. If the environment does not exist, then create the environment and activate it. This assumes that conda is already installed via Anaconda (or Miniconda).

# Create and activate a Python environment.

cmake_minimum_required(VERSION 3.18)

# Define the project
project(MyExample)

# Specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Make sure Python is installed
find_package(Python REQUIRED)

# Activate conda environment, assume Anaconda or Miniconda is already installed
if(EXISTS /opt/miniconda3/envs/myenv)
    execute_process(COMMAND conda activate myenv)
else()
    execute_process(COMMAND conda create --yes --quiet --name myenv python)
    execute_process(COMMAND conda activate myenv)
endif()

When I run the above cmake file, I get the error:

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.

However, conda is installed on my system and I can activate the environment manually in the terminal. Why does the environment not get activated via cmake?

wigging
  • 8,492
  • 12
  • 75
  • 117

1 Answers1

0

"Why does the environment not get activated via cmake?"

The first issue is in the error message, which indicates that the shell that CMake evaluates the execute_process command under doesn't know what conda activate means.

This could be because conda init <shell> has never been run for the particular shell that CMake uses (bash, perhaps?). This answer has some details on what conda init does. It could also be because the Conda initialization code that defines conda activate only gets loaded in interactive shells - which I wouldn't expect CMake to be using. There might be hacky ways to force execution in an interactive shell (bash -l -c 'conda activate foo'), but that doesn't matter because...

Even if the above were working, the procedures here don't make sense: a Conda environment's activation status is scoped to the shell process. I would expect that the (sub)shell dies with the completion of the execute_process. So, even if the activation worked, it wouldn't persist any further in the CMake script.

Discussion

Generally, this CMake script does not seem like a good approach. Tight-coupling the compilation of code to the existence of a particularly-named Conda environment at the user level seems to go against the spirit of CMake, which aims to automate the discovery of software dependencies so that users don't need commonly hardcoded locations. Perhaps it might be worth reassessing what is trying to be accomplished and the strategy to get there.

For example, on Conda Forge, lots of packages compile with CMake, but there CMake is executed in the context of an already activated environment and itself knows nothing about Conda. This makes it so the CMake code is completely agnostic to how its dependencies are provided, which I regard as cleaner engineering.

merv
  • 67,214
  • 13
  • 180
  • 245
  • 2
    Thank you for this great explanation. It sounds like the conda environment should be created and activated outside of cmake. And just use CMake for what it is intended to do which in my case is to build C++ code. – wigging Jun 02 '22 at 17:32
  • @wigging This is not really a solution. For example, you may want to integrate Python with Anaconda in C++. – Avrdan Feb 13 '23 at 11:00