Question: `Virtualenv` appends its own path to $PATH, effectively overwriting the Python to the one picked when the virtualenv is created. Would changing the $PATH work equivalently as virtualenv in a compiled language with shared libs?

I am asking this because it seems that there is no easy replacement of virtualenv for e.g. C (without firing up a VM/docker). I wonder if this is a theoretical constraint or just a technical challenge.

Operationally, I wonder what impossibilitates something like

```
activate
apt-get/brew install X
deactivate

```

where `activate/deactivate` do some magic for the package manager install in a specific location, and the compilation flags work accordingly (like `virtualenv` does for `pip`).

Answer: 
PATH and virtaulenv are totally different in the purpose they serve and how they work. As you said, virtualenv isolates a python interpreter and some libraries on your system from others and prevents new/other packages from either side bleeding over into the other.

The PATH on the other hand is fully named "the System's Executable's PATH". It tells the system where to look for the command you just entered, when you omitted the full path to it. So when you change the PATH for your C compiler, it only "helps" the system to find the compiler you want - usually you prepend the actual path you are interested in, this is searched first by the system, and magic happens.

This holds true only as long as the executables (e.g. your compiler) need to be found. Once it happens, everything starts again when you type in the next command. What's more important with the C compiler though, is that it doesn't find its libraries on the PATH (*for the notable exception that proves the rule, look at the end of my post*). First, every compiler is pre-configured with certain directories where to find its includes, and also other certain directories where to find it's C or C++ standard libraries. Beyond that, when you compile, you may give it additional directories where to look for system or third-party libraries. Once the compilation is complete, your system will look for it on the PATH when you type `executable` instead of `/full/path/to/executable` - but that is only to find it and start it. Your executable will look on the LDPATH (that is, system's library path) to find all the libraries that were referenced during compilation and it needs to run. And it will fail if any of those libraries are not reachable on the LDPATH.

There are tools, that can help you to create something similar to virtualenv for python, and they all have their quirks, so you need to read up on them before using. Nothing I know is as convenient as virtualenv though.

One of them is **chroot** - it isolates everything below a certain folder from the rest of the system and any process you start in a chrooted environment can use only what is available under this root folder. But you have to prepare the folder yourself - recreate the system folders that you want to have, copy all libraries that your isolated executable needs to the correct location, copy any other executables that might come in handy, copy their dependencies, config files, etc. to the correct location - all by hand - before you can start the isolated environment. Not as trivial as virtualenv.

**Note:** Only Windows does not distinguish between libraries and executables and looks for either of them on the executable PATH. That's why there it is possible to achieve the effect of isolating an executable by putting all DLLs (libraries) in the version that you need in the same folder as the executable. Then, if this specific folder is not included in the system PATH, the rest of the system is unaffected. When you start your software from within the directory it resides in, it finds its dependencies before trying the system's folders. This doesn't always work though, as libraries often have dependencies of their own and the more DLLs you use, the more complex task of finding and isolating their dependencies as well...
Virtualenv has a number of effects:

* it changes the PATH, which allows a different set of Python-related programs to become available.

	+ one of these programs is the Python interpreter, which affects the language version used.
* it changes the module paths, so modules are loaded from and installed to a location in the virtualenv.

For C programs:

* You can select the language version by using a different compiler, or providing a compiler option. How to do this depends on your compiler and build system.
* You can change the PATH to affect which programs are loaded.
* You can change include paths and linker paths at compile time/link time to affect which libraries are used. Read the documentation of your compiler and linker for details.

For dynamically loaded libraries, you can change the search path for shared objects, e.g. through the LD\_LIBRARY\_PATH variable.

As far as I know, there is no one-stop system like virtualenv to manage all of these in one go.

However, chroot (“change root”) may come in useful if you're dealing with absolute paths that you cannot change. This allows you to select a directory as the new root directory for a command, e.g.

```
chroot ./my-env command args...

```

This requires you to populate the `my-env` directory with all necessary files and programs first, which can be a lot of work. Also note that a chroot environment is not a container, and does not represent a security boundary – it just changes filename resolution of absolute paths. Nowadays, it's probably easier to use a Docker image for these use cases.