Saturday, July 28, 2012

How to compile C++ code in Notepad++ with gcc/g++

I use Notepad++ for all my coding.  It really is a great text editor.  These days I mostly use Perl so I don't have to worry about anything else, but I occasionally use C++ for speed in numerical tasks.  The system I've been using for years is to edit in Notepad++ then hop over to Dev-C++ to compile.  Dev C++ is an IDE that uses g++ to compile, so it's pretty silly to use it as a middle man.  Still, it has worked for years, and continues to.  The problem is that it hasn't been updated in a long time, and it still uses g++ 3.4.2 which is close to 10 years old.

I knew Notepad++ could run programs and that I could just compile directly via command line from it, I had just been too lazy to set it up.  I decided to make it work, and in researching how I found a lot of old info.  I decided to explain the process I used here for future reference.

The first step is to acquire nppexec, which used to be bundled with Notepad++ but isn't any more.  It comes as a zip of one dll and two folders, just put them all in the plugins folder of Notepad++.

Now you need gcc/g++.  MinGW is the standard way of doing this on Windows.  I went with this version because it came with a lot of useful libraries like boost.   Just extract that to some path with no spaces (spaces may work, but are generally a bad idea), and run the batch file.  You may need to add that path to the windows path system variable; I already had it in there from a past install of MinGW.  At this point test the install by running: g++ --version in a command prompt.  I have something like 5 versions of g++ floating around my computer, and it kept running an old version.  I finally just deleted that one.

Now open Notepad++ and hit F6 to bring up the execute window.  Here you can enter this code:
npp_save
cd "$(CURRENT_DIRECTORY)"
g++ "$(FILE_NAME)" -o $(NAME_PART) -march=native -O3

NPP_RUN $(NAME_PART)

I'll explain what each line does, so you can edit it as you see fit.  The first saves the current document.  Next changes the directory to the one the file is in.  Before this I kept compiling and couldn't find the executable.  It was in the Notepad++ folder.  Skipping the third for now, the last line runs the executable.

The third line does the actual compiling.  g++.exe "$(FILE_NAME)" should be clear, and -o $(NAME_PART) is the output filename.  -O3 uses the highest optimization level in g++.  There is some debate online as to whether the 3rd level is more trouble than it's worth.  A lot of people suggested that the 3rd was too aggressive, which could cause compile errors and is even sometimes slower than the 2nd level.  This wasn't unanimous though, and there weren't any references to actual examples.  Frankly, I felt like this was probably an example of cargo cult programming where it may have been true 15 years ago but people have just been repeating the same thing without ever stopping to reevaluate if it is still true.  In my exhaustive test of two programs it produced a program that was the same as level 2 as far as I could tell.  -march=native detects which instruction sets (eg SSE) are supported by the system doing the compiling and enables any that are.  This is a good option when the code will run on the same or similar system to the one compiling.

Anyway, once you have this code save it as something like 'Compile C++'.  You could create a few versions here, like one that doesn't run the code after compile, or that uses different flags.  I made one for interpreted languages that don't need compiling that is just:
npp_save
NPP_RUN $(FILE_NAME)


At this point, you are almost done.  Hitting F6 brings up that execute box where you can select which script to run.  Hitting Ctrl+F6 runs the last ran script.  However, I found hitting Ctrl+F6 to be annoying.  So I decided to remap it to just F5 (leaving F6 to bring up the box).  Under settings go to shortcut mapper.  Under main menu scroll down and find the command currently mapped to F5 (the simpler run box), and change it to something else or nothing.  Then under plugin commands find direct execute last, mapped to Ctrl+F6 and change it to F5.

That's it.  The first time you hit F5 in a document it brings up the box to let you pick which script to run.  Then every time after that it remembers and just runs it.

21 comments:

  1. Hum... I get an error code after executing the code... :(

    NPP_SAVE: C:\CODIGO\yuyu.cpp
    CD: C:\CODIGO
    Current directory: C:\CODIGO
    g++ "yuyu.cpp" -o yuyu -march=native -O3
    CreateProcess() failed with error code 2:
    El sistema no puede encontrar el archivo especificado.

    NPP_RUN: yuyu

    ReplyDelete
  2. If you get the error "CreateProcess() failed with error code 2" but g++ works from cmd, try restarting notepad++

    ReplyDelete
  3. Works on one machine but not another.

    NPP_SAVE: C:\Users\sid\Google Drive\School\Computer Logic\SortingBenchmarks.cpp
    CD: C:\MinGW\bin
    Current directory: C:\MinGW\bin
    g++ "C:\Users\sid\Google Drive\School\Computer Logic\SortingBenchmarks.cpp" -o SortingBenchmarks -march=native -O3
    Process started >>>
    g++: error: CreateProcess: No such file or directory
    <<< Process finished. (Exit code 1)
    NPP_RUN: SortingBenchmarks
    - the specified file was not found

    When I run it straight from the console it compiles with no issues.

    ReplyDelete
  4. NPP_SAVE: C:\Users\Rishi\cpp\hw.cpp
    CD: C:\Users\Rishi\cpp
    Current directory: C:\Users\Rishi\cpp
    g++ "hw.cpp" -o hw -march=native -O3
    Process started >>>
    cc1plus.exe: bad value (native) for -march= switch
    <<< Process finished. (Exit code 1)
    NPP_RUN: hw
    - the specified file was not found

    cold you please tell me how do i deal with the above error?

    ReplyDelete
  5. Thank you. I also have codeblock so I change the script to:

    NPP_SAVE
    CD $(CURRENT_DIRECTORY)
    C:\Program Files (x86)\CodeBlocks\MinGW\bin\g++.exe "$(FILE_NAME)" -o $(NAME_PART) -march=native -O3
    NPP_RUN $(NAME_PART)

    ReplyDelete
    Replies
    1. To prevent window from closing after execution in cmd, add "&& pause"

      SET g++ = C:\Program Files (x86)\CodeBlocks\MinGW\bin\g++.exe
      NPP_SAVE
      CD $(CURRENT_DIRECTORY)
      "$(g++)" "$(FILE_NAME)" -o "$(NAME_PART)" -march=native -O3
      NPP_RUN cmd /C "$(NAME_PART)" && pause

      Delete
    2. this does not work error occurred "specified file was not found"

      Delete
  6. to see output in NppExec console use this:
    npp_save
    cd "$(CURRENT_DIRECTORY)"
    g++ "$(FILE_NAME)" -o $(NAME_PART) -march=native -O3
    $(NAME_PART)

    for java program use this:
    npp_save
    cd $(CURRENT_DIRECTORY)
    javac $(FILE_NAME)
    java $(NAME_PART)

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. my c program process wont end. i manually have to open task manger every time to end the process. could you help me so that after final output the program process should terminate..

      such as after every final output it should show
      ================READY========

      which it does not. please help!!

      Delete
  7. The provided script didn't work for me. I use:

    NPP_SAVE
    set GWDIR=c:\MinGW
    cd $(CURRENT_DIRECTORY)
    $(GWDIR)\bin\g++.exe -g "$(FILE_NAME)" -o $(NAME_PART).exe

    To run I use:
    NPP_RUN pause.bat $(NAME_PART).exe

    Where "pause.bat" is a batch file I have in the local folder with the following in in to add a pause after the program executes:
    %1
    pause()

    ReplyDelete
    Replies
    1. Heh, running Windows10 and I get:

      c:\MinGW\bin\g++.exe -g "Test.h" -o Test.exe
      Process started >>>
      <<< Process finished. (Exit code 0)
      NPP_RUN: Test
      - the operating system denied access to the specified file
      ================ READY ================

      When using your script. This is the furthest that i've gotten out of any of the other scripts. I actually have an executable now. Unfortunately, the OS says no bueno.

      Delete
    2. Try saving your file as "Test.cpp"

      Delete
  8. I am getting the following error
    g++ "new 1.c" -o new 1 -march=native -O3
    CreateProcess() failed with error code 2:
    The system cannot find the file specified.

    ReplyDelete
    Replies
    1. I have the same issue, not really sure what's causing it though :c

      Delete
  9. NPP_SAVE: C:\Program Files (x86)\Notepad++\change.log
    CD: C:\Program Files (x86)\Notepad++
    Current directory: C:\Program Files (x86)\Notepad++
    g++ "change.log" -o change -march=native -O3
    Process started (PID=13900) >>>
    c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: cannot open output file change.exe: Permission denied
    collect2.exe: error: ld returned 1 exit status
    <<< Process finished (PID=13900). (Exit code 1)
    NPP_RUN: change
    ; executing: NPP_RUN change
    - the specified file was not found
    I dont understand why this is happening can you give any advice on how to fix this?

    ReplyDelete
    Replies
    1. What did you do to the code, did you modify it? have you saved your source file?

      Delete
  10. OMG, thank you sooooooooooooooooooooooooooooooo much for this tutorial

    ReplyDelete