Using OMNeT++ with Microsoft Visual C++
=======================================

Part of this documentation comes from a readme written by Balazs
KELEMEN (kelemen@sch.bme.hu) in March 2000.

*** IMPORTANT ***
  Since OMNeT++2.3b1, you have to compile both OMNeT++ and model files
  with exception handling and RTTI turned ON! Especially, if RTTI is not
  enabled, simulations will crash in the className() method.

  To run big simulations that use activity(), you should set a LOW (!)
  reserved stack size in the linker options: 64K (/stack:65536 linker
  flag) will do. This is because the Win32 Fiber API uses this number
  as coroutine stack size, and with the 1MB default, it is easy to run
  out of the 4GB possible address space (4GB/1MB=4096).
*** END ***


1. Prerequisites
~~~~~~~~~~~~~~~~
o  Windows XP, Windows 2000, NT 4.0 or other Windows versions which build
   on NT technology are required. (OMNeT++ is not supported and will not
   work on Win95, Win98 or ME.)

o  Visual C++ 7.0 (which is part of Visual Studio .NET) or Microsoft Visual
   Studio 6.0 with Service Pack 6 installed (the SP can be downloaded from
   Microsoft's site under the name vs6sp6.exe)

Since you're going to work a lot on the command-line, you'll probably want
to use some software which makes this easier. My suggestion is FAR Manager --
it is an excellent program, and will save you lots of typing.


2. Packages to download and install
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you use the binary release, you can skip this section, because the
package contains and the installer installs all other necessary software.

First download the following packages:
 - Tcl/Tk
 - BLT 2.4z
 - bison/flex (only if you want to modify nedxml/nedtool or gned)
 - Perl (used by some tools)
 - libxml, libxslt

3rdparty.txt lists additional optional packages that can be useful, and sites
where these packages can be downloaded from.

To unpack .tgz or .tar.gz (gzipped, tar packed) files you can use gzip and tar,
or ALZip or other archivers. Some versions of WinZip have been reported to
have difficulties with tgz files.

After installation, check if you have the necessary environment variables set.
These variables should be set by the install program of the related package.
(See Appendix A, and section "Checking and modifying environment variables")


3. Compiling OMNeT++
~~~~~~~~~~~~~~~~~~~~

If you're using the binary release, you can skip this section.

Download the omnetpp source code and documentation from the omnetpp site.
If you downloaded a zip file, extract its contents to the installation
directory. If you downloaded a tgz file, copy it to the directory where
you want to install OMNeT++, and extract the archive using the command:

    tar zxvf omnetpp.tgz

*** IMPORTANT ***
   AVOID DIRECTORY NAMES WITH SPACE, '+', OR ANY OTHER SPECIAL CHARACTER.
   Odds are that the compilation will choke. In particular, do NOT write
   "OMNeT++", because the copy shell command will misunderstand it
   for file concatenation. Use "omnetpp" instead.

In this text we'll assume that the directory which contains the
simulator files is called c:\omnetpp-3.0.

Make sure the MSVC executables (nmake,cl,link,...) are in the path.
The BIN directories of the VC should appear in the PATH environment variable.
They are C:\PROGRA~1\MICROS~1\VC98\BIN and C:\PROGRA~1\MICROS~1\MSDEV98\BIN
by default.

It is also recommended that you put the c:\omnetpp-3.0\bin directory
into the path. (See section "Checking and modifying environment variables",
appendix B)

Check the configuser.vc file to make sure it contains the proper settings.
You'll probably have to correct the following settings in it:
    OMNETPP_ROOT=
    TK_DIR=
    TK_VER=

Then type:
    nmake -f Makefile.vc
This should build the executables and the libraries and copy them to the bin
and lib subdirectories within the top-level omnetpp directory.

Note: As the Visual Studio IDE (and makefiles exported from the IDE)
accept only .cpp as an extension of a C++ file, the .cc files in the
samples/ directory will be renamed.

If you only want to create the executables or the libraries, type
    nmake -f Makefile.vc progs
    nmake -f Makefile.vc libs

To delete all built files, type
    nmake -f Makefile.vc clean

As the result of the compilation the following files should have been created:
In the bin directory:
    gned.exe nedtool.exe plove.exe scalars.exe ...

In the lib directory:
    sim_std.lib envir.lib cmdenv.lib tkenv.lib nedxml.lib


4. Building the samples from the MSVC IDE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To build a sample simulation, start MSVC and open the workspace (.dsw) file.
The simulation should build without any project file adjustment.

The top-level makefile automatically renames the .cc files to .cpp;
but if you want to do it manually, you can run samples/cc2cpp.bat.
The top-level makefile also automatically configures the project (.dsp)
files by substituting the correct Tcl/Tk version and library location.

*** NOTE ***
   BY DEFAULT, THE SAMPLE SIMULATIONS BUILT FROM THE MSVC IDE WILL USE THE
   COMMAND-LINE USER INTERFACE. To change to the graphical interface,
   choose Build|Set active configuration from the MSVC menu and select
   "Debug-Tkenv" or "Release-Tkenv", then re-link the executable.
   Choosing "Debug-Cmdenv" or "Release-Cmdenv" will revert to the command-line
   user interface.

If you need to modify the names of the Tcl/Tk libs (because you installed
a Tcl/Tk version other than 8.4), see Project|Settings --> 'Link' tab -->
choose 'Input' from combo --> Libraries.

*** NOTE ***
   While trying to build some of the samples in the MSVC IDE, you might
   get the following error, even if perl *is* in the PATH:

   Processing .\token.msg with opp_msgc
   'Perl is not recognized as an internal or external command, operable
   program or batch file. Error executing c:\windows\system32\cmd.exe

   This is probably a Visual Studio bug. I'm not sure under which
   circumstances it occurs. It was reported on Windows XP + MSVC 6.0 without
   a service pack (?), but I've been unable to reproduce it on Windows 2000 +
   MSVC 6.0 SP5. Anyhow, if this occurs on your PC, try one/both of the
   following:
     a) install Visual Studio Service Pack 5 (vs6sp5.exe) or later
     b) edit opp_msgc.cmd (in the ..\OMNeT++\bin directory) and
        supply the full path to perl.exe in line 4 (i.e. change "perl" to
        "c:\OMNeT++\bin\perl.exe", "c:\Perl\bin\perl.exe" or the location
        of your perl program)
   If this doesn't work out, please let me know. You can also try the
   workaround described in Mudassar Farooq's email to the mailing list
   on 2/18/2003, with subject "Perl Problem".

   Thanks to Farooq for finding out about this bug.


5. Creating your own simulations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can choose between using the MSVC IDE and makefiles+your favourite
programmer's editor (mine is MED). The latter one may seem more cumbersome,
but actually using the opp_nmakemake tool (described later) you can set up
the build environment within seconds.

If you opt for the MSVC IDE, you can set up the project file in the following
way:

 1. Start by copying and renaming one of the .dsp files from the samples
    directory. It already contains the necessary compiler/linker flags,
    Tkenv/Cmdenv configurations, and so on.

    You can also use the OMNeT++ App Wizard, available under
    File|New -> Projects in the MSVC IDE. This is automatically
    installed by the binary release.

 2. Adjust the project settings so that MSVC will find OMNeT++'s components
    that are needed to build simulation programs. Make sure you enter these
    settings for *all* configurations (In the Project|Settings dialog,
    select 'All configurations' from the combo in the top-left corner.)
    - include path: You must tell MSVC the location of omnetpp.h and other
      header files.  Add c:\omnetpp-3.0\include to the include path in
      Project|Settings --> 'C/C++' tab --> 'Preprocessor' category -->
      Additional include directories.
    - library path: MSVC needs to know where to find sim_std.lib, envir.lib
      and other libraries. Add omnetpp/lib to the linker path in
      Project|Settings --> 'Link' tab --> 'Input' category -->
      Additional library path.
    - nedc: It's advisable to put OMNeT++'s bin directory into the PATH
      so that MSVC will find the NED compiler. (An alternative is to enter
      explicit nedc path for each NED file's Custom build step, but that's
      much more cumbersome.)

 3. Add C++ files to the project. Note that they need to have .cpp extension.
    You might need to rename your .cc files to .cpp (ren *.cc *.cpp) and add
    them to the project.

 4. Add the .ned files to the project and set custom build option for them:
       Description:  NED Compiling $(InputPath)
       Command:      nedc -s _n.cpp $(InputPath)
       Outputs:      $(InputPath)_n.cpp
    Hint: you can select all .ned files together, and 'All configurations'
    from the combo at the left of the Settings dialog, and then you have to
    type this settings only once.
    Note: If you copied one of the sample projects, you'll have to adjust
    Command, because they contain explicit nedc path (..\..\bin\nedc).

 5. For each .ned file, add a corresponding _n.cpp file.
    Hint: if you 'Compile' the .ned files, the _n.cpp files will be created,
    and you can select them all at once in the 'Add files' dialog.

 6. Required compiler settings: exception handling ON, run-time type info
    (RTTI) ON. Also, set the necessary reserved stack size to 64K (needed
    for the Fiber API).

 7. Choose the appropriate configuration from Build|Set active configuration...
    Note: for Tkenv, the simulation will be linked with sim_std.lib, envir.lib,
    tkenv.lib and the Tcl/Tk libraries (link as Win32 Console app...).
    For Cmdenv, this will be sim_std.lib, envir.lib, and cmdenv.lib.

You may also use the OMNeT++ App Wizard and AddNEDFileToProject macro
(part of the OMNeT++ package) to ease some of these steps.


6. Using auto-generated makefiles
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

OMNeT++ can automatically generate makefiles for your simulations.
Open a command prompt, cd to the directory of your sources, then type

    opp_nmakemake

A file called Makefile.vc will be created, based on the source files you
currently have in the directory. Then you can build your simulation
simply by typing

    nmake -f Makefile.vc

opp_nmakemake accepts a number of command-line switches, run it with the
-h option to display a list. It allows models to span over multiple
directories, the makefile be extended by makefile fragments written by
you, etc.

The generated makefile includes configuser.vc from the c:\omnetpp-3.0
directory.


7. Reconfiguring the libraries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you need to recompile the OMNeT++ libraries with different flags (e.g.
for debugging or optimized for speed), then cd to the top-level omnetpp
directory, edit configuser.vc accordingly, then say:

    nmake -f Makefile.vc clean
    nmake -f Makefile.vc

If you want to recompile just a single library, then cd to the directory
of the library and type:

    nmake -f Makefile.vc clean
    nmake -f Makefile.vc

The built libraries and programs are immediately copied to the lib/ and bin/
subdirectories.


8. Using DLLs
~~~~~~~~~~~~~

It is possible to load a simulation model from a DLL. Suppose you have a DLL
called queueing.dll, which contains all modules from the "queueing" sample
simulation. Then you can load it into an appropriate sim.exe with the
following command-line:

    sim.exe -l queueing

This will cause sim.exe to load queueing.dll on startup, so you may now
use queueing simple modules in your simulations. The .dll filename extension
is added automatically (this allows for some degree of platform independence --
on Unix, .so is added.)  If you don't want to add the -l command-line option
every time, then adding

    [General]
    load-libs = "queueing"

to omnetpp.ini will also do the job. Multiple DLLs can also be loaded (use
multiple -l options, or load-libs="lib1 lib2 lib3 ..." in omnetpp.ini).

To build the DLL:

Create a file named makefrag.vc in the directory of the simple module sources
with the following content:

    # makefrag.vc -- settings for creating a dll
    EXPORTLIB= sim.lib

    TARGET= $(TARGET:.exe=.dll)
    LDFLAGS= $(LDFLAGS) /dll
    OMNETPP_LIBS= $(EXPORTLIB)
    COPTS= $(COPTS) /DWIN32_DLL
    NEDCOPTS= $(NEDCOPTS) /DWIN32_DLL

Adjust the EXPORTLIB= setting at the top: it should point to the export
library of the program you'll load the DLL into. (An export library is
automatically generated every time you build az OMNeT++ simulation executable,
with name <programname>.lib). The rest of the settings don't need to be
changed.

Then generate a Makefile.vc with the appropriate opp_nmakemake command
(makefrag.vc be inserted into the generated file.) Then if you just normally
build (nmake -f Makefile.vc), you should get a DLL as a result.

Note: the resulting DLL can only be loaded into the sim.exe whose export
library was used for building the DLL.


9. Misc notes
~~~~~~~~~~~~~
When using MSVC from the command line, you may get the error popup
"MSPDB60.DLL not found in the following path: ...". Funny is that the
displayed path includes MSDev98\Bin, where the MSPDB60.DLL resides indeed.
Solution is to copy this dll to the VC98\Bin directory.


Have fun!


Appendix A
~~~~~~~~~~
Check the existence of these environment variables (<variable>=<example value>):

MSVC variables:
 INCLUDE=%INCLUDE%;C:\PROGRA~1\MICROS~1\VC98\INCLUDE
 LIB=%LIB%;C:\PROGRA~1\MICROS~1\VC98\LIB
 Path=%PATH%;C:\PROGRA~1\Tcl\bin;C:\PROGRA~1\MICROS~1\Common\msdev98\BIN;C:\PROGRA~1\MICROS~1\VC98\BIN

Tcl/Tk variables:
 TCL_LIBRARY=C:\PROGRA~1\Tcl\lib\tcl8.4

Bison variables:
 BISON_SIMPLE=d:/home/tools/UnxUtils/usr/local/share/bison.simple

Note:
- Visual C++: As we use command line compilation, the BIN
  directory of the Visual C++ and the DLL directory of the Visual Studio
  should appear in the PATH environment variable.
  The lib and include directories should appear in the LIB and INCLUDE
  environment variables.

- Tcl/Tk requires the following:
  - the DLL directory of Tcl should appear in the PATH.
  - the TCL_LIBRARY environment variable should be set to the directory
    which contains init.tcl. It is usually the C:/PROGRA~1/Tcl/lib/tclx.x
    directory.


Appendix B:
~~~~~~~~~~
Checking and modifying environment variables

To see the list of environment variables, type "set" at the command prompt.
(To open a command prompt, select START-->Run...--> type "cmd"). If
the listing scrolls away, you may type "set | more" to page it, or
"set P" to list only the variables starting with "P".

Environment variables in Windows work in a similar way to Unix. Every process
has its own set of environment variables, inherited from the parent process
(This means that if you change the environment variable settings, you may
need to exit and restart programs for them to pick up changes; sometimes
you may even need to log out and log in again.)

To locally and temporarily change environment variables in a command prompt
window, you can use the "set VARIABLE=value" command. Remember, however,
that this change will only affect programs that you'll run from that
command line window.

In Windows there is a GUI to permanently change environment variables.
Bring up My Computer-->Properties. On Windows 2000 there'll be an
"Environment" tab; on XP choose the "Advanced" tab and click the
"Environment variables" button to bring up much the same dialog. The dialog
lets you view, add and modify environment variables. After you've done
the settings, log out and log in again.

Managing environment variables is also discussed in several Microsoft Knowledge
Base articles, e.g. 310519. Go to support.microsoft.com and type "environment
variables" in the Search box.

