HOWTOlabs Microsoft Windows
Code Development FAQ

Development under Microsoft Windows splits into general development of remote code, essentially using Windows as a development terminal, and platform development for Windows native applications.  Remote code development is made somewhat awkward as many Linux and OS X tools purposely designed for remote development are not native to MS Windows.  Native MS Windows development essentially means using Microsoft Visual Design Studio application suite.

Remote Development

Essential Downloads [edit]

Elsewhere [edit]

Typically remote development is using a MS Windows based computer to connect to non-Windows servers for development and administration purposes.  For this to be effect need a remote terminal to invoke Linux/Unix commands directly, a file transfer tool to upload/download file securely, and a powerful text editor for code development that works in concert with a robust file transfer mechanism.

Archive

Contents
  • Source Editing Alternatives & Tips
  • MSVC - running in 'non-debug' mode
  • MSVC - library link anomolies
  • MSVC - include file anomolies
  • MSVC - custom build rules
  • NMAKE - example of a hand coded makefile file
  • WinCVS - popular source code version control

CodeWright
To enter hexidecimal edit mode either right click the mouse and select it from the pop up menu, or use the keyboard equicelent H


MSVC - running in 'non-debug' mode

F5 invokes executable in Debug mode. Shift F5 will invoke executable with no debugging enabled. Its amazing how quickly I forget this subtle distinction.


MSVC - include file anomolies

Microsoft Visual Studio C++ resolves include files in a non-intuitive manner.

There are two ways to augment MSVC's include path. The nasty way it to hard code it in the Tools/Option/Diretcory control panel. This can cause problems because it card codes C:\ ... in the path. However it does target all projects. More flexible is to add /I directives in the C/C++ control panel. However this has to be done for each project target.

Standard convention for most compilers when resolving a #include is to look in standard system include directories before looking in a project's custom include directories. Often this is explicitly set up in the makefile for the project.

Under certain circumstances the MSVC Integrated Development Environment (IDE) will NOT look in the standard system include directory first. This situation arises when a custom header has the same name as a standard system header AND the project's preprocessor settings have additional include directories listed (e.g. /I fooinc). In this case the standard header files that happen to have the same name as custom headers will be incorrectly found first in the additional include directories. Any code or definitions relying on the the proper standard header file being processed will spaz out and often generate very misleading compile error messages.

To resolve this, either rename your header file to something more unique, or remove the project's preprocessor additional include directories setting and hard code the source code to include (e.g. #include "/fooinc/math.h").
/*  std C lib headers
 *  MSVC IDE will read these from its internally stored std include path  */
#include <windows.h>
#include <stdlib.h>
#include <math.h>  /*  if /I fooinc set in project settings
                       this will be misread from fooinc/math.h  */
#include <stdio.h>
#include <sys/timeb.h>

/*  custom headers
 *  MSVC IDE will read these directly from current path  */
#include "fooinc/cop.h"
#include "fooinc/math.h"  /*  custom header  */
#include "fooinc/time.h"
#include "fooinc/class.h"


MSVC - library link anomolies

The MSVC linker will generate warnings in certain situations. Typically this happens when additional libraries are specified. Changing the library order can resolve this. For example:

BAD:
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
winmm.lib ../lib/jpeg.lib

Linking...
LINK : warning LNK4098: defaultlib "LIBC" conflicts with use of other
libs; use /NODEFAULTLIB:library

dev.exe - 0 error(s), 1 warning(s)


GOOD:
../lib/jpeg.lib winmm.lib 
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

Linking...

dev.exe - 0 error(s), 0 warning(s)


MSVC - custom build rules

Following adds a custom build rule to create config.h by making a copy of win_config.h
  1. create a dummy file called config.h
  2. Right click on 'project' files, pop-up menu, add file
  3. pop-up file requestor, hilite dummy 'config.h' file, ok
  4. GO back to 'project' files, find and hilite dummy config.h file, pop-up menu, setting
    Commands: copy win_config.h config.h
    Outputs: config.h
    Dependencies: win_config.h
  5. Now file explorer, delete dummy config.h file.
  6. Now make (shortcut F7)
    Should copy win_config.h -> config.h automatically when first dependency needs it

Note: beware that Project Settings - Custom Build may overide the per file custom rules. This can be very disorienting if it is set to bad rule since a correct rule on the file will be ignored :-(


NMAKE - example of a hand coded makefile file

Microsoft has their own peculiar command line make utility called NMAKE. In concept is it pretty similar to the real man's UNIX and GNU Linux make. However, non-trivial makefiles for use with NMAKE are not compatble with the latter make, and care must be used when constructing them for use under Microsoft's empire.

Here's a non-trival NMAKE makefile example. It compiles source from three different source code directories into a single object directory. Then performs a link of all the object files into a single library.

TARGET = ismoglmd.lib
TARGETDIR = ..\..\lib64

CPP = cl
RSC = rc.exe
F90 = df.exe
MTL = midl.exe

OBJDIR = ismoglmd


CPP_PROJ=/nologo /MD /W3 /Zp8 /Gy -cbstring /Wp64 \
	/Gz /Gi- /GX- /GR- /GF -Z7 /Oxs /Zx /Gs8192 \
	/QIA64_fr32 /d2nowarn4715 /QIA64_A0 /Oy- \
	/I "\dism\inc" /I "\dism\inc\plugins" \
	/D "ISM_OGL" /D "WIN32" /D "_WINDOWS" \
	 /Fr$(OBJDIR)\\ /Fo$(OBJDIR)\\ /Fd$(OBJDIR)\\ /c

LIB32= link.exe -lib
LIB32_FLAGS = /nologo /out:\dism\lib64\$(TARGET)


OGL_DIR = ..\..\ismsrc\ogl
OBJS_OGL = \
	$(OBJDIR)\appgl.obj \
	$(OBJDIR)\camgl.obj \
	$(OBJDIR)\GLPRIM.OBJ \
	$(OBJDIR)\imagegl.obj \
	$(OBJDIR)\lightgl.obj \
	$(OBJDIR)\meshgl.obj \
	$(OBJDIR)\newscene.obj \
	$(OBJDIR)\surfgl.obj


CORE_DIR = ..\..\ismsrc\core
OBJS_CORE = \
	$(OBJDIR)\quat.obj \
	$(OBJDIR)\cmatrix.obj \
	$(OBJDIR)\vtxanim.obj \
	$(OBJDIR)\appearbase.obj \
	$(OBJDIR)\ARRAY.OBJ \
	$(OBJDIR)\Box.obj \
	$(OBJDIR)\Cam.obj \
	$(OBJDIR)\distscene.obj \
	$(OBJDIR)\DualScene.obj \
	$(OBJDIR)\Engine.obj \
	$(OBJDIR)\fog.obj \
	$(OBJDIR)\Geodraw.obj \
	$(OBJDIR)\GeoMesh.obj \
	$(OBJDIR)\Geonorm.obj \
	$(OBJDIR)\GEOUTIL.OBJ \
	$(OBJDIR)\Group.obj \
	$(OBJDIR)\Image.obj \
	$(OBJDIR)\ismapp.obj \
	$(OBJDIR)\ismbufpool.obj \
	$(OBJDIR)\ismprim.obj \
	$(OBJDIR)\ismpool.obj \
	$(OBJDIR)\ismwinapp.obj \
	$(OBJDIR)\Light.obj \
	$(OBJDIR)\lightdev.obj \
	$(OBJDIR)\loadq.obj \
	$(OBJDIR)\Mat.obj \
	$(OBJDIR)\Model.obj \
	$(OBJDIR)\multitex.obj \
	$(OBJDIR)\Obj.obj \
	$(OBJDIR)\Scene.obj \
	$(OBJDIR)\scenethread.obj \
	$(OBJDIR)\Shape.obj \
	$(OBJDIR)\socketStream.obj \
	$(OBJDIR)\Sphere3.obj \
	$(OBJDIR)\Stream.obj \
	$(OBJDIR)\Surf.obj \
	$(OBJDIR)\TriMesh.obj \
	$(OBJDIR)\vtxAOS.obj \
	$(OBJDIR)\vtxbase.obj

PLUGINS_DIR = ..\..\ismsrc\plugins
OBJS_PLUGINS = \
	$(OBJDIR)\BB.OBJ \
	$(OBJDIR)\ImageSwitch.obj \
	$(OBJDIR)\keyframe.obj \
	$(OBJDIR)\LOD.OBJ \
	$(OBJDIR)\MTBb.obj \
	$(OBJDIR)\pathplay.obj \
	$(OBJDIR)\portal.obj \
	$(OBJDIR)\room.obj \
	$(OBJDIR)\roomgroup.obj \
	$(OBJDIR)\sprite.obj \
	$(OBJDIR)\switch.obj \
	$(OBJDIR)\switcher.obj \
	$(OBJDIR)\texswitcher.obj \
	$(OBJDIR)\textimage.obj \
	$(OBJDIR)\vHandyTools.obj \
	$(OBJDIR)\vMorphEng.obj \
	$(OBJDIR)\vSkinVoxEng.obj \
	$(OBJDIR)\wall.obj \
	$(OBJDIR)\xreffile.obj \
	$(OBJDIR)\xformer.obj


# This is a comment
$(TARGETDIR)\$(TARGET): $(OBJDIR) $(OBJS_CORE) $(OBJS_OGL) $(OBJS_PLUGINS)
    $(LIB32) $(LIB32_FLAGS) $(OBJS_CORE) $(OBJS_OGL) $(OBJS_PLUGINS)


{.\$(CORE_DIR)}.cpp{$(OBJDIR)}.obj::
	$(CPP) $(CPP_PROJ) $<

{.\$(OGL_DIR)}.cpp{$(OBJDIR)}.obj::
	$(CPP) $(CPP_PROJ) $<

{.\$(PLUGINS_DIR)}.cpp{$(OBJDIR)}.obj::
	$(CPP) $(CPP_PROJ) $<


$(OBJDIR):
    if not exist "$(OBJDIR)/$(NULL)" mkdir "$(OBJDIR)"
	-@erase /S /Q $(OBJDIR)
WinCVS Client - Installation

Get the latest version of WinCVS. As of this writing ...

Now make sure you have a account user/passwd and the know the server to login to. You may need to ask your system administrator for this info. (Sysadmin Note: make sure the new user is added to the cvs group).

After installation is successful, run WinCVS. A Preferences requestor should be displayed

Now the main WinCVS Window should come up. At this point the menu for CVS Admin - Login. When you will be away from your system it is a good idea to - Logout from this menu.

CVS Admin - Checkout Module will allow a source code directory to be checked out from the CVS server to your system. It usually will bring up a Select Directory to checkout to requestor. Make sure you have a prepared directory in which you would like to download source code.

WinCVS Client - Tips

View Menu - You can constrain the folders displayed in the left file browser area by selecting Change Browser Location

New folders do not show
If some time has elapsed since you checked out a project to a working directory, any new directories created in the repository are not automatically downloaded with the update command. See the Create missing directories that exist in the repository update option setting.

More CVS tips