Environment Variables in CLion

Permalink:

The following is a Stack Overflow question I asked (and answer I subsequently gave). I thought it was a well-researched and potentially useful, if somewhat niche, Q&A pair. If nothing else, IMO it’s a model Stack Overflow question and I want to signal-boost it.

(If you’re not in the know, JetBrains CLion is a great cross-platform C/C++ IDE.)

The Question

I want to be able to source one or more environment variables from a file within a particular run/debug configuration in JetBrains CLion. As far as I’m aware and as of this writing, this particular question has not been answered on Stack Overflow. I think it should be useful for users of other JetBrains IDEs.

Coming from a mostly Python background, I’ve made a lot of use of the Python dotenv library to define several environment variables in a file. The syntax in these files looks like

VARIABLE_NAME=value

This looks similar to how I’d define (local) variables in a shell script.

Other languages that I’ve worked with in the past have modules (e.g., Julia, Node) or built-in functionality (e.g., R) that all follow this VARIABLE=value syntax. I would expect that sourcing environment variables from a file in an IDE should have a similar feel.

Either CLion does not and I just don’t know it, or I’ve stumbled onto a misconfiguration (more likely) or a bug (less likely).

What this question is not

I’m not trying to set CMake variables. I want to set environment variables to be visible to my program through std::getenv.

An answer on a related question recommends a plugin which is not compatible with CLion. Moreover, support for sourced environment files in a run/debug configuration is already built in to CLion, so a plugin shouldn’t be necessary.

What I tried

Minimal working example

Here is a simple C++ program which prints out an environment variable:

#include <iostream>

int main() {
    auto test_val = getenv("TEST");
    std::cout << "TEST value: " << test_val << std::endl;
}

and here are the contents of /home/alan/Documents/20201222-clion-env-file-test/env:

TEST=hello

(I’ve tried with and without a newline, but it doesn’t make any difference.)

Broken run/debug configuration

Attempting to source an environment variable from this file appears not to work:

CLion run/debug configuration (not working)

Expected output

/home/alan/Documents/20201222-clion-env-file-test/cmake-build-debug/20201222_clion_env_file_test
TEST value: hello

Process finished with exit code 0

Actual output

/home/alan/Documents/20201222-clion-env-file-test/cmake-build-debug/20201222_clion_env_file_test
TEST value: 
Process finished with exit code 0

Working run/debug configuration

Explicitly defining the variable works:

CLion run/debug configuration (working)

Expected output

/home/alan/Documents/20201222-clion-env-file-test/cmake-build-debug/20201222_clion_env_file_test
TEST value: hi

Process finished with exit code 0

Actual output

/home/alan/Documents/20201222-clion-env-file-test/cmake-build-debug/20201222_clion_env_file_test
TEST value: hi

Process finished with exit code 0

tl;dr

Why is CLion not picking up my environment variables if I set them from a file?

System info

CLion 2020.3
Build #CL-203.5981.166, built on December 1, 2020
...
Runtime version: 11.0.9+11-b1145.21 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
Linux 5.8.0-7630-generic

The Answer

CLion does not follow the expected syntax, but the documentation is not explicit about that:

Use the Load variables from file field to point CLion to a script that configures the environment.

The clue is the word script. If you want the environment variable to be available outside the script, you need to export it, same as you would in the shell:

alan@just-testing:~/Documents/20201222-clion-env-file-test$ cat ./env 
TEST=hello
alan@just-testing:~/Documents/20201222-clion-env-file-test$ source ./env && ./cmake-build-debug/20201222_clion_env_file_test 
TEST value: alan@just-testing:~/Documents/20201222-clion-env-file-test$

Making the requisite changes gives the expected result:

alan@just-testing:~/Documents/20201222-clion-env-file-test$ cat env 
export TEST=hello
alan@just-testing:~/Documents/20201222-clion-env-file-test$ source ./env && ./cmake-build-debug/20201222_clion_env_file_test 
TEST value: hello

Here is the output from CLion after making this change:

/home/alan/Documents/20201222-clion-env-file-test/cmake-build-debug/20201222_clion_env_file_test
TEST value: hello

Process finished with exit code 0

If you have any recent C/C++ experience, this is probably obvious, but if you came up on interpreted languages with the VARIABLE=value syntax, like I did, this is definitely not obvious.