Emacs on Microsoft Windows

Table of Contents

Top

1 Emacs on Microsoft Windows

1.1 Overview

Why Emacs on Windows ?

Emacs provides many useful tools for Windows developers or anyone that have to use Windows for professional reasons or use Windows at work such as:

  • Powerful terminal emulator: Emacs can be a powerful terminal emulator for Windows and a outstanding replacement for cmd.exe terminal emulator because it has history, multi line history and multi line input and tiling windows where it is possible to split the Emacs window and run a repl and edit a file on the same window. Unlike cmd.exe Emacs can also run multiple REPLs in the same window.
  • Run any shell: Emacs can run any shell application like Python, IPython, Powershell, cmd.exe, bash, C# shell, F# and so on.
  • Eshell: Eshell is unix-like shell implemented in Elisp providing many unix commands like ls, mv, cp, rm without any external dependencies and it is also highly integrated to Emacs allowing the user to call elisp functions, browser directories, open files (visit buffer).
  • Dired mode: Dired mode allows fast directory navigation and to run commands or apply shell commands on files like md5sum, rm -rf, git add and so on.

1.2 Getting Emacs and Useful tools

1.2.1 Getting Emacs

Emacs 32 bits

Emacs 64 bits - 64-Bit GNU Emacs for MS Windows with optimization.

Install using Chocolately Package Manager

Emacs 64 bits unnoficial

choco install emacs64

1.2.2 Getting Unix utilities

Git for Windows provides many Unix utilities ported for Windows like awk, cat, ls, chown, grep, find and etc.

c:/Program Files/Git/usr/bin $ ls -l *.exe
-rwxrwxrwx   1 Administrators None        65017 2016-03-18 16:40 [.exe
-rwxrwxrwx   1 Administrators None        28991 2016-03-18 16:40 arch.exe
-rwxrwxrwx   1 Administrators None       581408 2015-05-21  2015 awk.exe
-rwxrwxrwx   1 Administrators None        37712 2016-03-18 16:40 base32.exe
-rwxrwxrwx   1 Administrators None        37712 2016-03-18 16:40 base64.exe
-rwxrwxrwx   1 Administrators None        30078 2016-03-18 16:40 basename.exe
-rwxrwxrwx   1 Administrators None      2063362 2016-07-13 16:00 bash.exe
-rwxrwxrwx   1 Administrators None        89618 2014-11-04  2014 bunzip2.exe
-rwxrwxrwx   1 Administrators None        89618 2014-11-04  2014 bzcat.exe
-rwxrwxrwx   1 Administrators None        89618 2014-11-04  2014 bzip2.exe
-rwxrwxrwx   1 Administrators None        14686 2014-11-04  2014 bzip2recover.exe
-rwxrwxrwx   1 Administrators None        74003 2016-03-01 17:15 captoinfo.exe
-rwxrwxrwx   1 Administrators None        51896 2016-03-18 16:40 cat.exe
-rwxrwxrwx   1 Administrators None        55848 2016-03-18 16:40 chcon.exe

...

-rwxrwxrwx   1 Administrators None       128615 2016-03-18 16:40 vdir.exe
-rwxrwxrwx   1 Administrators None      2335971 2016-04-09 11:08 view.exe
-rwxrwxrwx   1 Administrators None      2335971 2016-04-09 11:08 vim.exe
-rwxrwxrwx   1 Administrators None      2335971 2016-04-09 11:08 vimdiff.exe
-rwxrwxrwx   1 Administrators None        42100 2016-03-18 16:40 wc.exe
-rwxrwxrwx   1 Administrators None        29553 2015-07-20  2015 which.exe
-rwxrwxrwx   1 Administrators None        63429 2016-03-18 16:40 who.exe
-rwxrwxrwx   1 Administrators None        28054 2016-03-18 16:40 whoami.exe
-rwxrwxrwx   1 Administrators None       975360 2016-05-16 14:32 winpty-agent.exe
-rwxrwxrwx   1 Administrators None        41984 2016-05-16 14:32 winpty-debugserver.exe
-rwxrwxrwx   1 Administrators None       747008 2016-05-16 14:32 winpty.exe
-rwxrwxrwx   1 Administrators None        64058 2016-01-20 15:17 xargs.exe
-rwxrwxrwx   1 Administrators None        25299 2016-03-29 14:28 xmlwf.exe
-rwxrwxrwx   1 Administrators None        18954 2016-04-09 11:08 xxd.exe
-rwxrwxrwx   1 Administrators None        28580 2016-03-18 16:40 yes.exe
-rwxrwxrwx   1 Administrators None       173708 2014-11-04  2014 zipinfo.exe

GNU Make is an useful build-automation tool and can be got from:

$ choco install make

1.3 Useful Tweaking

1.3.1 Setting Environments Variables

  1. Set HOME

    The HOME environment variable that has the default value /home/<username>) on Linux sets the user's directory path.

    This variable, which is equivalent to _%USERPROFILE% _(C:\\Users\<username> ) is expected to be set by many Unix applications ported to Windows and it also makes directory browser in Emacs and shells easier.

    C:\Users\arch>echo %USERPROFILE%
    C:\Users\arch
    

    It can be set permanently by using the commmand below on cmd.exe shell.

    setx HOME %USERPROFILE%
    

    To test if the variable is set. Open a new cmd.exe shell and type:

    C:\Users\arch>echo %HOME%
    C:\Users\arch
    

    It allows to browser Windows directories as:

    ~ C:\Users\arch
    ~/Desktop C:\Users\arch\Documents
    ~/.emacs.d C:\Users\arch\.emacs.d

    It also allows the commands:

    To open file ~/.emac.d/init.el (C:\Users\arch\.emacs.d\init.el)

    • C-x C-f find-file ~/.emac.d/init.el

    To open directory (C:\Users\arch\Desktop)

    • C-x C-d ~/Desktop
  2. Set PATH

    Executables located in directories listed in PATH environment variable can be invoked without its full path like ls, echo and who in Unix-like OS or ipconfig, arp and whoami in Windows.

    C:\Users\arch\bin>echo %PATH%
    C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem...
    

    By adding the directory ~/bin or C:\Users\<user>\bin to PATH variable it makes easir to call command line applications from this directory without specifing its full path from Emacs or shell (cmd.exe). It can be done with:

    • Add the directory C:\Users\<user>\bin to %PATH% enviroment variable:
    setx PATH "%PATH%;%USERPROFILE%\bin"
    

    It makes easeir to call C:\Users\<user>\bin\curl.exe from any directory. Instead of write its full path the user can just run $ curl.exe or $ curl.

1.3.2 Invert Control and Capslock

The Ctrl (Control) key is one of the most used keys, although it is one of the most inconvenient and ergonomically bad key to type possible leading to strain injury when used often as in Emacs. On the other hand, Capslock while in a convenient position is one of the most useless keys as it is not used often and upper case letters can be typed just by holding the shift key while typing the underlying letter. Those problems can be overcome by mapping the Capslock key to Ctrl and Ctrl to Capslock. On Windows it can be done by running the commands below in the powershell as administrator and then rebooting or by entering in the cmd.exe shell and typing $ powershell and then pasting the mentioned commands.

$hexified = "00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00".Split(',') | % { "0x$_"};
$kbLayout = 'HKLM:\System\CurrentControlSet\Control\Keyboard Layout';
New-ItemProperty -Path $kbLayout -Name "Scancode Map" -PropertyType Binary -Value ([byte[]]$hexified);

1.3.3 Initialization - init.el file.

This section provides a minimal configuration for Windows to deal with pitfalls and annoyances.

  • Suppress startup screen
(setq inhibit-startup-message t)
  • Suppress Windows annoying beep or bell - Visible bell
(setq-default visible-bell t)
  • Do not open file or user dialog.
(setq use-file-dialog nil)
(setq use-dialog-box nil)
  • Use Unix's \n (LF- Line Feed) and utf instead of Windows \r\n (CRLF - Carriage Return and Line Feed) as end of line character. It may not be desirable if most files or project edited are for Windows or building tools that may fail if the source file doens't CRLF as line ending.
(setq-default buffer-file-coding-system 'utf-8-unix)
  • UTF8 Everywhere
(set-terminal-coding-system 'utf-8)
(set-language-environment 'utf-8)
(set-keyboard-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
  • Separate Customization file from init.el
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerror)
  • Handy key bindings for invoking compilation command.
    • Type F9 to call M-x compile
    • Type Ctrl + F9 to call M-x recompile - running the compilation command again.
(global-set-key (kbd "<f9>") #'compile)

(global-set-key (kbd "<C-f9>")
                (lambda () (interactive)
                  (save-buffer)
                  (recompile)                
                  ))

1.4 Unix utilities

You can bash install with Chocolately package manager or download GIT version control app that comes bundled with bash and Unix utilities like grep, mv, ssh, df and dd.

Command to run Bash. Usage: M-x run-bash

(defun run-bash ()
      (interactive)
      (let ((shell-file-name "C:\\Program Files\\Git\\bin\\bash.exe"))
            (shell "*bash*")))

Command to run cmd.exe. Usage: M-x run-cmdexe

(defun run-cmdexe ()
      (interactive)
      (let ((shell-file-name "cmd.exe"))
            (shell "*cmd.exe*")))

1.5 Environment Variables in Emacs

To run Unix utilities and other command lines apps in Emacs add to the PATH system environment variable the path to their directories like this:

(setenv  "PATH" (concat

                ;; "c:/Windows/System32" ";" 

                 "c:/Windows/Microsoft.NET/Framework/v4.0.30319" ";"

                 "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319" ";"

                 ;; Unix tools 
                 "C:\\Program Files\\Git\\usr\\bin" ";"

                 ;; User binary files 
                 "C:\\User\\arch\\bin" ";"

                 ;; Mono Installation.
                 "c:\\Program Files\\Mono\\bin" ";"

                 "c:\\Program Files\\Mono\\lib\\mono\\4.5" ";"

                 (getenv "PATH")

         ))

1.6 Shells

1.6.1 Eshell

  1. Overview

    Eshell provides many benefits to Windows users:

    • Many unix like commands implemented on Emacs' Lisp like: mv, cp, which …
    • Completion
    • History: C-c C-l
    • Easy copy and paste unlike cmd.exe
    • Integration with Eamcs since it can run Emacs commands (interactive functions) like shell commands.
  2. Screenshots

    eshell-windows-demo1.png

  3. Demonstrations
    1. Commands and history

      To open the history type: C-c C-l

      eshell-windows-demo1.gif

    2. Emacs Integration

      Eshell can run Emacs elisp commands (interactive functions) like find-file, dired as ordinary shell commands like is shown above.

      The function find-file can be executed in eshell as shell command find-file ~/.emacs.d/init.el .

      (find-file "~/.emacs.d/init.el")
      

      Some useful Elisp commands on Eshell:

      Open file:

      • find-file
      • find-file-other-window
      • find-file-other-frame

      Open directory:

      • dired
      • dired-other-window
      • dired-other-frame
    3. Asyncrhonous Commands
      ~/Desktop $ notepad.exe &
      
    4. Copy command output to clibpoard

      Eshell comes with a pseudo clipboard device /dev/kill that is useful to handle clipboard.

      Copy command output to clibpboard

      ~/Desktop $ ipconfig.exe > /dev/kill
      

      Show clibpoard content

    5. Shell Commands mixed with Emacs commands

      Note: split-string Is an Emacs function.

      Example 1:

      ~/Desktop $ split-string $PATH ";" 
      
      (#("C:/Program Files (x86)/Microsoft SDKs/F#/4.0/Framework/v4.0" 0 59
         (escaped t))
       #("c:/Windows/System32" 0 19
         (escaped t))
       #("c:/Windows/Microsoft.NET/Framework/v4.0.30319" 0 45
         (escaped t))
       #("C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319" 0 45
         (escaped t))
       #("C:\\Program Files\\Git\\usr\\bin" 0 28
         (escaped t))
       #("C:\\User\\arch\\bin" 0 16
         (escaped t))
       #("c:\\Program Files\\Mono\\bin" 0 25
         (escaped t))
       #("c:\\Program Files\\Mono\\lib\\mono\\4.5" 0 34
         (escaped t))
       "")
      ~/Desktop $
      

      Exmaple 2:

      ~/Desktop $ for m in {split-string $PATH ";"} {echo $m}
      
      C:/Program Files (x86)/Microsoft SDKs/F#/4.0/Framework/v4.0
      c:/Windows/System32
      c:/Windows/Microsoft.NET/Framework/v4.0.30319
      C:\Windows\Microsoft.NET\Framework\v4.0.30319
      C:\Program Files\Git\usr\bin
      C:\User\arch\bin
      c:\Program Files\Mono\bin
      c:\Program Files\Mono\lib\mono\4.5
      ~/Desktop $
      

      Example 3:

      ~/Desktop $ for m in $load-path { echo $m}
      
      e:/projects/org-wiki
      ~/.emacs.d/packages
      c:/Users/arch/.emacs.d/elpa/csharp-mode-20160901.319
      c:/Users/arch/.emacs.d/elpa/fsharp-mode-20160719.315
      c:/Users/arch/.emacs.d/elpa/flycheck-20160817.321
      c:/Users/arch/.emacs.d/elpa/company-quickhelp-20160211.718
      c:/Users/arch/.emacs.d/elpa/company-20160730.1516
      c:/Users/arch/.emacs.d/elpa/helm-anything-20141126.231
      c:/Users/arch/.emacs.d/elpa/anything-20160822.1852
      c:/Users/arch/.emacs.d/elpa/helm-20160824.745
      ...
      

1.6.2 Powershell

This command runs Powershell on Emacs:

(defun run-powershell ()
  "Run powershell"
  (interactive)
  (async-shell-command "c:/windows/system32/WindowsPowerShell/v1.0/powershell.exe -Command -"
               nil
               nil))

Usage: M-x run-powershell.

1.7 Visual C++ MSVC Building Tools

1.7.1 Calling MSVC tools from Emacs

Calling the default and official Windows' C++ compiler MSVC (Microsoft Visual C++) from command line is not easy as calling gcc, mingw or clang as MSVC needs environment variables INCLUDE, LIB, LIBPATH and PATH to be properly set with correct paths. Those settings depends on the version of the compiler and the building target x86 (32 bits) or x64 (64 bits), so the path settings of MSVC 2015 are different from MSVC 2017. This section provides useful commands that solve this problem by allowing the user call the compiler directly which may be useful for studying c++ on Windows, learning about Windows API, testing the compiler, building simple C++ programs or creating proof-of-concepts.

Note: It was tested with MSVC 2017 and Windows10.

To use it just copy the functions to the file ~/.init.el or emacs intialization file.

  • Porgram:

Saves the original PATH variable

(defvar msbuild-old-path-var (getenv "PATH"))

This command sets environments variables for MSVC - 2017 Building tools and x68 building target. If the user runs M-x msbuild-2017-x86-setup, it will allows to call the msvc compiler cl.exe with M-x compile cl.exe file.cpp. Then, the code will be compiled for x86 target. It is also possible to call with M-x compile the commands msbuild.exe, link.exe (MSVC's linker) and dumpbin.exe (similar to GNU objdump).

(defun msbuild-2017-x86-setup ()
  "Set enviorment variables to load Microsoft Visual C++ Compiler (MSVC 32 bits)"
  (interactive)
  (message "Setting 32 bits MSVC building tools.")
  (setenv "PATH" msbuild-old-path-var)
  (setenv "INCLUDE"
        (concat
             "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/ATLMFC/include"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/include"
         ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/include/um"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/ucrt"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/shared"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/um"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/winrt"
         ))

  (setenv "LIB"
        (concat
             "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/ATLMFC/lib/x86"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/lib/x86"
         ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/lib/um/x86"
         ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/ucrt/x86"
         ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/um/x86"             
         ))

  (setenv  "LIBPATH"
         (concat
              "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/ATLMFC/lib/x86"
          ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/lib/x86"
          ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/lib/x86/store/references"
          ";" "C:/Program Files (x86)/Windows Kits/10/UnionMetadata/10.0.16299.0"
          ";" "C:/Program Files (x86)/Windows Kits/10/References/10.0.16299.0"
          ";" "C:/Windows/Microsoft.NET/Framework/v4.0.30319"
          ))

  (setenv "PATH"
        (concat
         (getenv "PATH")
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/bin/HostX86/x86"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/VC/VCPackages"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/CommonExtensions/Microsoft/TestWindow"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/MSBuild/15.0/bin/Roslyn"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Team Tools/Performance Tools"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/Shared/Common/VSPerfCollectionTools/"
         ";" "C:/Program Files (x86)/Microsoft SDKs/Windows/v10.0A/bin/NETFX 4.6.1 Tools/"
         ";" "C:/Program Files (x86)/Microsoft SDKs/F#/4.1/Framework/v4.0/"
         ";" "C:/Program Files (x86)/Windows Kits/10/bin/x86"
         ";" "C:/Program Files (x86)/Windows Kits/10/bin/10.0.16299.0/x86"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community//MSBuild/15.0/bin"
         ";" "C:/Windows/Microsoft.NET/Framework/v4.0.30319"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/Tools/"
         )))

The command below sets enviroment variable for MSVC - 2017 and x64 building target and its similar to msbuild-2017-x86-setup.

(defun msbuild-2017-x64-setup ()
  "Set enviorment variables to load Microsoft Visual C++ Compiler (MSVC) 64 bits"
  (interactive)
  (message "Setting 64 bits building tools.")
  (setenv "PATH" msbuild-old-path-var)
  (setenv "INCLUDE"
        (concat
             "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/ATLMFC/include"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/include"
         ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/include/um"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/ucrt"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/shared"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/um"
         ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/winrt"
         ))

  (setenv "LIB"
        (concat
             "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/ATLMFC/lib/x64"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/lib/x64"
         ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/lib/um/x64"
         ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/ucrt/x64"
         ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/um/x64"             
         ))

  (setenv  "LIBPATH"
         (concat
              "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/ATLMFC/lib/x64"
          ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/lib/x64"
          ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/lib/x64/store/references"
          ";" "C:/Program Files (x86)/Windows Kits/10/UnionMetadata/10.0.16299.0"
          ";" "C:/Program Files (x86)/Windows Kits/10/References/10.0.16299.0"
          ";" "C:/Windows/Microsoft.NET/Framework/v4.0.30319"
          ))

  (setenv "PATH"
        (concat
         (getenv "PATH")
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/bin/HostX86/x64"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/VC/VCPackages"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/CommonExtensions/Microsoft/TestWindow"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/MSBuild/15.0/bin/Roslyn"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Team Tools/Performance Tools"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/Shared/Common/VSPerfCollectionTools/"
         ";" "C:/Program Files (x86)/Microsoft SDKs/Windows/v10.0A/bin/NETFX 4.6.1 Tools/"
         ";" "C:/Program Files (x86)/Microsoft SDKs/F#/4.1/Framework/v4.0/"
         ";" "C:/Program Files (x86)/Windows Kits/10/bin/x64"
         ";" "C:/Program Files (x86)/Windows Kits/10/bin/10.0.16299.0/x64"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community//MSBuild/15.0/bin"
         ";" "C:/Windows/Microsoft.NET/Framework/v4.0.30319"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/IDE/"
         ";" "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/Common7/Tools/"
         )))

This command allows to compile the current buffer. For instance, if the current buffer is associated to a file test1.cpp and user types M-x compile-msvc-x86, it will show a prompt with cl.exe test1.cpp asking the user to confirm or complement the compilation command.

(defun compile-msvc-x86()
  (interactive)
  (msbuild-2017-x86-setup)
  (let ((compile-command (format "cl.exe \"%s\""
                                 (file-name-nondirectory (buffer-file-name))))
        (compilation-ask-about-save nil))
    (call-interactively #'compile )))

(defun compile-msvc-x64 ()
  (interactive)
  (msbuild-2017-x64-setup)
  (let ((compile-command (format "cl.exe \"%s\""
                                 (file-name-nondirectory (buffer-file-name))))
        (compilation-ask-about-save nil))
    (call-interactively #'compile )))

The screenshot below shows an example about how those commands can be used:

emacs-msvc-windows.png

Test file: codes/test.cpp

#include <iostream>

using namespace std;

int main(){

  for(int i = 1 ; i < 10; i ++)
    cout << "Testing C++ on Emacs in Windows VM" << endl;

  return 0;
}

1.7.2 Commands for MSVC2015

M-x msbuild-2015-x86-setup and Set environment variables to allow calling cl.exe for x86 build target and other tools from M-x compile and shell commands.

(defun msbuild-2015-x86-setup ()
  (interactive)
  "Set enviorment variables to load Microsoft Visual C++ Compiler 2015 (MSVC) 32 bits"
  (setenv "PATH" msbuild-old-path-var)
  (setenv "INCLUDE"
          (concat 
           "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/ucrt"
           ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/include/um"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/shared"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/um"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/winrt"
           ))
  (setenv "LIB"
          (concat
           "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/LIB"
           ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/ucrt/x86"
           ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/lib/um/x86"
           ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/um/x86"
           ))
  (setenv "LIBPATH"
          (concat 
           ";" "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/LIB"
           ";" "C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319"
           ";" "C:/WINDOWS/Microsoft.NET/Framework/"
           ";" "C:/Program Files (x86)/Windows Kits/10/UnionMetadata"
           ";" "C:/Program Files (x86)/Windows Kits/10/References"
           ";" "C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/1.0.0.0"
           ";" "C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.FoundationContract/1.0.0.0"
           )) 
  (setenv "PATH"
          (concat
           (getenv "PATH")
           ";" "C:/Program Files (x86)/MSBuild/14.0/bin"
           ";" "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/BIN"
           ";" "C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319"
           ";" "C:/WINDOWS/Microsoft.NET/Framework/"
           ";" "C:/Program Files (x86)/Windows Kits/10/bin/x86"
           ";" "C:/Program Files (x86)/Microsoft SDKs/Windows/v10.0A/bin/NETFX 4.6.1 Tools/"
           )))

M-x msbuild-215-x64-setup - Similar to previous command.

(defun msbuild-2015-x64-setup ()
  (interactive)
  "Set enviorment variables to load Microsoft Visual C++ Compiler 2015 (MSVC) 64 bits"
  (setenv "PATH" msbuild-old-path-var)
  (setenv "INCLUDE"
          (concat 
           "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/ucrt"
           ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/include/um"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/shared"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/um"
           ";" "C:/Program Files (x86)/Windows Kits/10/include/10.0.16299.0/winrt"
           ))
  (setenv "LIB"
          (concat
           "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/LIB/amd64"
           ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/ucrt/x64"
           ";" "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.6.1/lib/um/x64"
           ";" "C:/Program Files (x86)/Windows Kits/10/lib/10.0.16299.0/um/x64"
           ))
  (setenv "LIBPATH"
          (concat 
           "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/LIB/amd64"
           ";" "C:/WINDOWS/Microsoft.NET/Framework64/v4.0.30319"
           ";" "C:/WINDOWS/Microsoft.NET/Framework64/"
           ";" "C:/Program Files (x86)/Windows Kits/10/UnionMetadata"
           ";" "C:/Program Files (x86)/Windows Kits/10/References"
           ";" "C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.UniversalApiContract/1.0.0.0"
           ";" "C:/Program Files (x86)/Windows Kits/10/References/Windows.Foundation.FoundationContract/1.0.0.0"           
           )) 
  (setenv "PATH"
          (concat
           (getenv "PATH")
           ";" "C:/Program Files (x86)/MSBuild/14.0/bin/amd64"
           ";" "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/BIN/amd64"
           ";" "C:/WINDOWS/Microsoft.NET/Framework64/v4.0.30319"
           ";" "C:/WINDOWS/Microsoft.NET/Framework64/"
           ";" "C:/Program Files (x86)/Windows Kits/10/bin/x64"
           ";" "C:/Program Files (x86)/Windows Kits/10/bin/x86"
           ";" "C:/Program Files (x86)/Microsoft SDKs/Windows/v10.0A/bin/NETFX 4.6.1 Tools/x64/"
           )))

Commands to compile file related to current c++ buffer.

(defun compile-msvc-2015-x86()
  (interactive)
  (msbuild-2015-x86-setup)
  (let ((compile-command (format "cl.exe \"%s\""
                                 (file-name-nondirectory (buffer-file-name))))
        (compilation-ask-about-save nil))
    (call-interactively #'compile )))

(defun compile-msvc-2015-x64 ()
  (interactive)
  (msbuild-2015-x64-setup)
  (let ((compile-command (format "cl.exe \"%s\""
                                 (file-name-nondirectory (buffer-file-name))))
        (compilation-ask-about-save nil))
    (call-interactively #'compile )))

1.7.3 Install C++ Compilers and MSVC Building Tools

The esiest and fastest way to install MSVC building tools is by using the chocolately package manager which provides a Linux-like experience for installing packages.

Install Visual C++ Build Tools 2015 14.0.25420.1

$ choco install visualcppbuildtools

Install Visual Studio 2017 Build Tools 15.2.26430.20170650

$ choco installvisualstudio2017buildtools

Install Mingw - gcc/g++ GNU C/C++ Compiler ported for Windows

$ choco install mingw

1.7.4 Build automation tools and batch files

Batch files (*.bat extensions) can be used as *nix Makefiles to perform build-automation on Windows, compile C++, C, and C# programs and also perform a wide variety of tasks.

Example: This file build.bat compiles and run the file test1.cpp with Visual C++ compiler. To build the C++ file codes/test.cpp, it just to put this file to the directory to the directory where is test.cpp and then type in Emacs M-x build or M-x build.bat.

The build script can also be executed using the Windows shell cmd.exe, by entering $ cd <project> and then typing build or build.bat. It can also be run by double clicking at the file build.bat.

File: codes/build.bat

@echo off
rem  Compile for x86 or x64 bits 
rem ------------------------------
set MODE=x86          
rem set MODE=x64   
@REM Visual studio building tools path - Install it with chocolately 
set VS2017="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsamd64_x86.bat"
set VS2015="C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat" 
rem Save current directory     
pushd %CD%
@REM Set visual Studio 2017 
call %VS2017% %MODE% 
@REM Restore saved directory     
popd 
@REM ------------------ User Command Goes Here ----------------- @REM             
@REM Build solution in Debug mode
cl.exe  test.cpp && test.exe 
@REM Set /p Wait=Build Process Completed...

This build script can be adapted to use other Windows building tools, for instance, the line where is cl.exe could be replaced with:

  • $ msbuild WpfAppLearning.sln /p:Configuration=Release /p:Platform="Any CPU"
    • To build a Visual studio solution (aka project).
  • $ Devenv WpfAppLearning.sln /Rebuild Debug
    • Rebuild applicatio with Visual Studio Command line switch.
  • $ fsc.exe app1.fsx <flags>
    • Compile a F# application
  • $ csc.exe app1.cs
    • Compile a C# application
  • $ scalac app1.scala -d app1.jar && scala app1.jar
    • Compile a Scala application and run it.

It is also worth knowing some DOS / Windows command line tools for compiling applications on Windows.

Description Unix, Linux, MacOSX and BSD Windows, MSDOS and OS/2
Show Command Help bash –help set /?, cl.exe /? ..
     
Show current User whoami whoami
Show path of application or executable which bash where notepad.exe
Clear terminal clear cls
     
Go to directory, aka path cd <path>; cd <path>
Go to Disk or Mount Point $ cd /mnt/mount-point $ C:, $ D:, $ E: ..
Change to a different directory cd cd
     
List directory ls <dir> dir <dir>
List file directory in chronological order with detail ls -ltr dir /od
Make a new directory mkdir mkdir or md
Delete a directory rmdir rmdir or rd
     
Display contents of a text file cat <file> type <file>
Copy a file, preserving its date-time stamp cp -p copy <file> <dest>
Delete a file rm <file> erase <file> OR del <file>
Move a file mv <file> <new-name> move
Rename a file mv ren
Find a file find dir /s
Grep a file grep findstr
Display differences between two text files diff fc
Change file attributes chmod attrib
“Super-user” root authorization sudo N/A
Create symbolic link to a file or directory ln N/A
     
Show environment variables env set
Set environment variable export PATH=$PATH:/dir/bin set PATH=%PATH%;E:/dir/bin
Set environment variable permanently N/A setx <VARIABLE>=<VALUE>
Redirect command output to file   set
     
Open file dor directory with default system application xdg-open file1.ppt start file1.ppt
     
Shrink executable file size strip strip (included w/ Free Pascal)
     
  • Note:
    • xdg-open only exists on Linux or BSD with X11
    • On MacOSX the equivalent is open

Created: 2018-07-26 Thu 07:42

Emacs 25.3.1 (Org mode 8.2.10)

Validate