Showing posts with label environment variables. Show all posts
Showing posts with label environment variables. Show all posts

Monday, 17 January 2022

Linux Environment Variables

 

Working with Environment Variables

To list all environment variables and their values use:

$ env

To display the value of some particular env var use echo $ENV_VAR_NAME. Example:

$ echo $GOPATH
/home/test_user/dev/go

To set environment variables for the single command:

Example:

$ env GOOS=linux GOARCH=amd64 go build cmd/main.go

From the executable's point of view, the same would have been achieved without using env:

$ GOOS=linux GOARCH=amd64 go build cmd/main.go

To set environment variables for the current terminal session:

$ export GOPATH=/mnt/c/dev/go

export is a bash builtin. export key=value is extended syntax and should not be used in portable scripts (i.e. #! /bin/sh)

What's the difference between set, export and env and when should I use each?
What is the difference between set, env, declare and export when setting a variable in a Linux shell?

If some bash script calls executable which requires some env variables, we also need to use export.Example:

demo.sh:

#!/bin/bash
...
echo
echo Env variables:
go env
export CGO_ENABLED=0
export GOOS=linux
export GOARCH=amd64 
echo
echo Env variables:
go env
go build -o './bin/myapp' -v './cmd/main.go'

...gives the output:

Env variables:
[16:33:25][Step 4/7] GOARCH="amd64"
[16:33:25][Step 4/7] GOOS="linux"
[16:33:25][Step 4/7] CGO_ENABLED="1"
...
[16:33:25][Step 4/7] 
[16:33:25][Step 4/7] Env variables:
[16:33:25][Step 4/7] GOARCH="amd64"
[16:33:25][Step 4/7] GOOS="linux"
[16:33:25][Step 4/7] CGO_ENABLED="0"
...

How do I add environment variables?
How to set an environment variable only for the duration of the script?

To add en environment variable during the session of a particular user (and also make them available in terminal) append the desired var name and its value to ~/.profile file. Example:

export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

We'd need to restart the terminal in order to get these changes visible but to make terminal fetch them in the current session, we can update the current shell session with:

source ~/.profile

Alternatively we could have used a dot command:


. ~/.profile 



To add a new or modify existing environment variable permanently (to make environment variable persistent) (for non-root user) we need to change ~/.bashrc:

Example of ~/.bashrc snippet:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
...
export GOPATH=$HOME/dev/go
export PATH=$PATH:$GOPATH/bin


To do the same for root user, open /etc/environment:

$ sudo gedit /etc/environment

...and add desired path:

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
GOPATH="/home/test_user/dev/go"

 

 

Linux Default Environment Variables


user@host:~/$ echo $HOSTNAME
host

 

 

Monday, 3 October 2011

NMAKE and its environment

nmake is a Microsoft's command-line tool for building C/C++ applications. nmake comes with Visual Studio and Windows Driver Development Kit (DDK) and it comes in two versions: one for building 32-bit and another for building 64-bit binaries. Here is the list of its locations, depending on which Microsoft product is installed on your machine:

Visual Studio 2010:
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\nmake.exe
(32-bit binary; depends on 32-bit advapi32.dll, kernel32.dll and msvcr100.dll)

C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\nmake.exe
(64-bit binary; depends on 64-bit advapi32.dll, kernel32.dll and msvcr100.dll)

Visual Studio 2008:
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\nmake.exe
(32-bit binary; depends on 32-bit advapi32.dll, kernel32.dll and msvcr90.dll)

C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\nmake.exe
(64-bit binary; depends on 64-bit advapi32.dll, kernel32.dll and msvcr90.dll)

Windows DDK (I have some pretty old installed on my machine):
C:\WinDDK\6001.18001\bin\x86\nmake.exe
(32-bit binary; depends on 32-bit advapi32.dll, kernel32.dll and msvcr80.dll)

C:\WinDDK\6001.18001\bin\ia64\nmake.exe
(64-bit binary; depends on 64-bit advapi32.dll, kernel32.dll and msvcr80.dll)

Binaries from amd64/ia64 directories are 64-bit and cannot be run on 32-bit machines.

msvcrXX.dll is Microsoft Visual C Runtime library. XX is its version, specific for each version of Visual Studio: 80 for VS2005, 90 for VS2008 and 100 for VS2010. Binary linked against some msvcr library requires existence of that library on the machine it runs on. If it does not exist, it can be installed with Microsoft Visual C++ VS20XX Redistributable Package (x86 or x64).

If you want to run some particular nmake on your machine, make sure its path is listed in Paths environment variable. If there are more versions of nmake present on your machine, put path to desired version before paths to the other versions. E.g. put path "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin" before "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin" in Paths if you want to run VS2010 nmake. You can always check which nmake will be called from some arbitrary location if executing (from a command line):

where nmake

If nmake resides in multiple directories, all those directories will be listed but only instance from the first listed will be called,
nmake reads instructions from a file called makefile (full name of this file usually does not contain a dot and extension). Instructions of how to build a specific binary (or binaries) are grouped into named targets. Those instructions contain compiler and linker calls, provided with source files, paths to headers, dependencies, object file names and compiler and linker options. Tags for groups of targets or sets of instructions that don't make binaries (like creating or deleting files or directories) are pseudo-targets.

You need to provide target or pseudo-target name when calling nmake. You can provide path to makefile; without it nmake looks for it in the current directory.

makefile contains instruction to call Microsoft compiler, cl.exe and linker, link.exe. Just like nmake, they come with Visual Studio and Windows DDK.

Visual Studio 2010:
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\cl.exe
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\link.exe
(64-bit compiler and linker for AMD64 architecture)

c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\cl.exe
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\link.exe
(32-bit compiler and linker for building 32-bit applications)

c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\cl.exe
(depends on advapi32.dll, kernel32.dll, msvcr100.dll, version.dll, psapi.dll and shell32.dll from C:\Windows\System32 and mspdb100.dll from c:\program files\microsoft visual studio 10.0\common7\ide)

c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\link.exe
(depends on advapi32.dll, kernel32.dll, msvcr100.dll, psapi.dll and user32.dll from C:\Windows\System32 and mspdb100.dll from c:\program files\microsoft visual studio 10.0\common7\ide) (32-bit cross-compiler and linker for building 64-bit applications for AMD64 architectures)

c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_ia64\cl.exe
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_ia64\link.exe
(32-bit cross-compiler and linker for building 64-bit applications for Itanium architectures)

Visual Studio 2008:
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\cl.exe
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\link.exe

c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\cl.exe
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\link.exe

c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\x86_amd64\cl.exe
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\x86_amd64\link.exe

c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_arm\cl.exe
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_arm\link.exe

c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_mips\cl.exe
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_mips\link.exe

c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_sh\cl.exe
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_sh\link.exe

Windows DDK:
c:\WinDDK\6001.18001\bin\ia64\ia64\cl.exe
c:\WinDDK\6001.18001\bin\ia64\ia64\link.exe
c:\WinDDK\6001.18001\bin\x86\amd64\cl.exe
c:\WinDDK\6001.18001\bin\x86\amd64\link.exe
c:\WinDDK\6001.18001\bin\x86\ia64\cl.exe
c:\WinDDK\6001.18001\bin\x86\ia64\link.exe
c:\WinDDK\6001.18001\bin\x86\x86\cl.exe
c:\WinDDK\6001.18001\bin\x86\x86\link.exe

Again, which compiler and linker will be called depends on paths listed in Path environment variable. Paths used can be checked by calling (from a command line):

where cl.exe
where link.exe

For example, if we want to build some 64-bit application for AMD architecture (which is usually named x64 and is more common than Itanium one) and we we want to build it on 32-bit machine, using VS2010, we need to use cross-compiler and so will add following paths to Path environment variable:
C:\Windows\System32; (path to dlls used by cl.exe and link.exe)
c:\program files\microsoft visual studio 10.0\common7\ide; (path to dlls used by cl.exe and link.exe)
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64; (path to cl.exe and link.exe)
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin; (path to nmake.exe)

If you try to run 64-bit compiler on 32-bit machine, you'll get message:
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64>cl.exe /?
This version of c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\cl.ex
e is not compatible with the version of Windows you're running. Check your compu
ter's system information to see whether you need a x86 (32-bit) or x64 (64-bit)
version of the program, and then contact the software publisher.

You can run 32-bit compiler or 32-bit cross-compiler on 32-bit machine only:
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64>cl.exe /?
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

This is not enough for nmake build to be successful. Compiler reads paths to Visual C++ and Windows SDK (Windows Framework) headers from INCLUDE environment variable. These headers are coming with each version of Visual Studio and we need to make sure cl.exe will be using correct ones. For example, if we want to use VS2010, we will set INCLUDE as:
c:\Program Files\Microsoft Visual Studio 10.0\VC\include; (Visual C++ headers - part of Microsoft's implementation of C++ standard)
c:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include; (ATL/MFC headers - add this path only for this type of applications)
c:\Program Files\Microsoft SDKs\Windows\v7.0A\include; (Windows SDK headers)

Furthermore, linker reads paths to Visual C++ and Windows Framework libraries from LIB environment variable. These libraries are specific for each version of Visual Studio and target architecture. If using VS2010 and building binary for AMD64 architecture, we would set LIB as:
c:\Program Files\Microsoft Visual Studio 10.0\VC\lib\amd64; (Visual C++ libraries)
c:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\lib\amd64; (ATL/MFC libraries- add this path only for this type of applications)
c:\Program Files\Microsoft SDKs\Windows\v7.0A\lib\x64; (Windows SDK libraries)

Of course, if your application depends on some other framework or package, INCLUDE needs to contain path to its headers and LIB path to its libraries.

I wrote one short batch file for setting Visual Studio environment (environmental variables) for x86 or x64 builds:
setenv.bat (caret character is used to break long lines):
@rem B.Komazec Setting environment for using Microsoft Visual Studio 2010 x86/x64 tools.
@echo off

@if "%1"=="x86" goto set_x86
@if "%1"=="x64" goto set_x64
@if "%1"=="" goto error

:set_x86
@echo Setting environment for using Microsoft Visual Studio 2010 x86 tools.

set INCLUDE=^
c:\Program Files\Microsoft Visual Studio 10.0\VC\include;^
c:\Program Files\Microsoft SDKs\Windows\v7.0A\include;

set LIB=^
c:\Program Files\Microsoft Visual Studio 10.0\VC\lib;^
c:\Program Files\Microsoft SDKs\Windows\v7.0A\lib;

set PATH=^
%SystemRoot%\system32;^
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin;^
c:\program files\microsoft visual studio 10.0\common7\ide;

goto test_bin_locations

:set_x64
@echo Setting environment for using Microsoft Visual Studio 2010 x64 tools.

set INCLUDE=^
c:\Program Files\Microsoft Visual Studio 10.0\VC\include;^
c:\Program Files\Microsoft SDKs\Windows\v7.0A\include;

set LIB=^
c:\Program Files\Microsoft Visual Studio 10.0\VC\lib\amd64;^
c:\Program Files\Microsoft SDKs\Windows\v7.0A\lib\x64;

set PATH=^
%SystemRoot%\system32;^
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64;^
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin;^
C:\Program Files\Microsoft Visual Studio 10.0\Common7\ide;

goto test_bin_locations

:test_bin_locations
@echo on
where nmake
where cl.exe
where link.exe
@echo off
goto:eof

:error
@echo Usage: setenv.bat [x86^|x64]

goto:eof

For example, to set environment for building x64 (AMD64) application with VS2010, call this script providing "x64" as an argument:

setenv x64

Note that changes made with SET will remain only for the duration of the current CMD session. To check the value of some environment variable in command prompt window use ECHO command followed by environment variable surrounded with percent signs:

echo %Path%

You can also use batch files that come with Visual Studio:
Visual Studio 2010:
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_ia64\vcvarsx86_ia64.bat
C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat

Visual Studio 2008:
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\vcvarsamd64.bat
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat
C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat

Links and references:
NMAKE Reference (MSDN)
An introduction to Makefiles
Nmake Makefile Tutorial and Example
CL Environment Variables
LINK Environment Variables
Setting the Path and Environment Variables for Command-Line Builds

Wednesday, 24 August 2011

Axis2/C Windows binary package and OpenSSL

I deployed Axis2C (1.6.0, Windows binary distribution) on IIS 7.0 running on Windows Server 2008 but simple browser-based test (http://localhost/axis2/services) failed - I got HTTP error 500 in W3SVC log:

#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken
2011-08-24 09:02:53 ::1 GET /axis2/services - 80 - ::1 Mozilla/5.0+(compatible;+MSIE+9.0;+Windows+NT+6.0;+Trident/5.0) 500 0 0 421

Page in the browser displayed:

An IIS server error occurred
An error occurred while initilizing Axis2/C.

Axis log file showed:

[error] ..\..\util\src\class_loader.c(167) Loading shared library C:\axis2c/lib/axis2_http_sender.dll Failed. DLERROR IS DLL Load Error 126: The specified module could not be found.

I used Process Explorer to find Axis2C DLLs loaded by IIS working process and here they are:

axiom.dll
axis2_engine.dll
axis2_parser.dll
axutil.dll
guththila.dll
mod_axis2_iis.dll
neethi.dll

Some of these modules failed to load axis2_http_sender.dll. I tried to reload aforementioned URL in order to wake up w3wp.exe and make it load Axis2C modules. Process Monitor was filtering w3wp.exe events and I could see that w3wp failed to find libeay32.dll (QueryOpen would return NAME NOT FOUND for all locations listed in PATH environment variable). This dll is a part of OpenSSL and is not included in original Axi2C binary package. I downloaded OpenSSL and, just for a test, placed libeay32.dll in C:\axis2c\lib, where axis2_http_sender.dll resides. This time Process Monitor showed that ssleay32.dll could not be found. This file, just like libeay32, belongs to OpenSSL. I placed it in C:\axis2c\lib and repeated the test. Voila! I got the list of my services listed in the browser which proved that Axi2C was set properly.

Process Explorer now shows the complete list of Axis2C DLLs loaded by w3wp.exe:

axiom.dll
axis2_engine.dll
axis2_http_receiver.dll
axis2_http_sender.dll
axis2_mod_addr.dll
axis2_mod_log.dll
axis2_parser.dll
axutil.dll
guththila.dll
libeay32.dll
ssleay32.dll
mod_axis2_iis.dll
neethi.dll

Conclusion: Axis2C Windows distribution depends on OpenSSL DLLs which are not included in binary package which can be downloaded from Apache Axis2/C Releases page. OpenSSL must be installed separately. Unfortunately, this is not mentioned in Axis2/C manual.

Note: upon installing OpenSSL on your system, path to its binaries (e.g. c:\openssl\bin) should be added to PATH environment variable. Make sure you restart machine after changing environment variables as IIS gets them only upon restart - it does not lookup their update values!

Note: If OpenSSL support is not required, download Axis2C source and built it with OpenSSL disabled (--enable-openssl=no)

References and links:
Axis2/C built with SSL support. axis2_http_sender.dll fails to load
problems running default http server
axis2/c depending on openSSL
re-distribute openSSL dlls with AXIS2/c and patent issue

Wednesday, 10 August 2011

Visual Studio, Directories and Environment Variables

Visual Studio 2010 does not allow setting user-specific paths to include files and libraries at the global level but instead these paths must be set in the user property sheet VC++ Directories which is automatically added to every project. Go to Properties->Configuration Properties->VC++ Directories and there you'll find various paths:

  • Executable Directories - path that corresponds to environmental directory PATH
  • Include Directories - path that corresponds to environmental directory INCLUDE
  • Reference Directories - path that corresponds to environmental directory LIBPATH
  • Library Directories - path that corresponds to environmental directory  LIB
  • Source Directories
  • Exclude Directories

The fact that Visual Studio treats these paths as if they were set in environment variables allows us to use the same semantics used when setting environment variables. E.g. we can reference value of some arbitrary environment variable in the path. For example, if WINDDK_PATH is environment variable which value is path to Windows DDK, we can reference its value as $(WINDDK_PATH). Path to DDK API headers in Include Directories is then $(WINDDK_PATH)\inc\api.

NOTE 1: Value of arbitrary environment variable named ENV_VAR can be echoed in Command Prompt window by executing "echo %ENV_VAR%" command.

NOTE 2: Visual Studio/Command Prompt  must be restarted in order to fetch latest changes in environment variables.