[SDK] Using Microsoft Visual C++ 2005 Express Edition

I am compiling with Visual Studio 9.0 and I am not able to get everything working. I have run into several problems; can anybody suggest a solution? I am using refar's guide and the 3.19 makefile to compile pure vanilla BTS (3.19) first.

1. Makefile gives option /G7 but VS9 does not recognize it. Easy solution, delete /G7 from the Makefile.

2. Some files such as CvGame.cpp and CvGameInterface.cpp give errors due to a variable out of scope, like:

for (int i=0; i<5; i++) { ... do some stuff ... }
for (i=0; i<5; i++) { ... do some other stuff ... }

The second reference of i has no declaration since i went out of scope at the first close curly. This is true, but probably earlier compilers were not so picky. The solution to this one, via the microsoft website, is to add option /Zc:forscope- to the makefile. Also no problem.

I do not find any mention of forscope in this thread so it is not clear how anybody has gotten VS9 to work.

(EDIT: removed a user error to unclutter the thread ... and avoid looking stupid)
 
I haven't used 2009, only 2008+ Express Edition. But what I understand is that the actual program you use doesn't matter at all, because the Makefile forces you to install under 2003 rule sets. So unless 2009 is refusing to be equal to 2008 in terms of backward compatibility, that shouldn't be an issue. It may be worth installing 2008+ Express just to find out though (if you can have those two installed concurrently).

And yes, 2003 rules allow a lot of those scope errors to fly by without issue, which is kinda horrible.
 
I think we are using the same thing. The banner and help-about of what I have installed is, "Visual C++ 2008 Express". The name of its install directory is Microsoft Visual Studio 9.0.

I can now compile, but when I go to run, it complains msvcp90.dll is not found. This is clearly on the system somewhere. Do I need to add a compiler search path to the makefile somewhere?

EDIT1: The file itself is located in ...Microsoft Visual Studio 9.0/vc/redist/x86/microsoft.vc90.crt. I have tried copying the file to ...Microsoft Visual Studio 9.0/vc/lib, which is referenced in the makefile. I have also tried copying it to the mod directory where I have put CvGameCoreDLL.dll, and also into the BTS directory itself where Civ4BeyondSword.exe lives. None of those have any effect. I am pretty sure I want to add something about this into the makefile, so that I do not have to include the file in my distribution zipfile.

Can anybody who got compilation working with VC++ Express 2008 / VS 9.0 comment about this file msvcp90.dll?

EDIT2: Re-reading the instructions, I had never copied the three dll's msvcrt.lib,msvcrtd.lib,msvcprt.lib into the vc/lib directory. I did this, and things got worse. I get hundreds of unresolved external references like:
Spoiler :

CyGameCoreUtilsInterface.obj : error LNK2001: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A)
CyGameInterface.obj : error LNK2001: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A)
CyGameTextMgrInterface.obj : error LNK2001: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A)
CyGlobalContextInterface1.obj : error LNK2001: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A)
CvDLLPython.obj : error LNK2019: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A) referenced in function "public: char const * __thiscall boost::python::type_info::name(void)const " (?name@type_info@python@boost@@QBEPBDXZ)
Project : error PRJ0019: A tool returned an error code from "Performing Makefile project actions"
CyAreaInterface.obj : error LNK2001: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A)
CyArtFileMgrInterface.obj : error LNK2001: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A)
CyCityInterface1.obj : error LNK2001: unresolved external symbol "struct __type_info_node __type_info_root_node" (?__type_info_root_node@@3U__type_info_node@@A)
CvGameTextMgr.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: wchar_t * __thiscall std::allocator::allocate(unsigned int)" (__imp_?allocate@?$allocator@_W@std@@QAEPA_WI@Z) referenced in function "protected: bool __thiscall std::vector >::_Buy(unsigned int)" (?_Buy@?$vector@_WV?$allocator@_W@std@@@std@@IAE_NI@Z)
CvGameTextMgr.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall std::allocator::deallocate(wchar_t *,unsigned int)" (__imp_?deallocate@?$allocator@_W@std@@QAEXPA_WI@Z) referenced in function "protected: void __thiscall std::vector >::_Tidy(void)" (?_Tidy@?$vector@_WV?$allocator@_W@std@@@std@@IAEXXZ)
Final_Release\CvGameCoreDLL.dll : fatal error LNK1120: 16 unresolved externals

As soon as I replace the original libraries from the VS9 directory, these errors go away, but I still cannot run because of the msvcp90.dll error. So I am still stuck. Anybody?

EDIT3: Sigh. I had completely misunderstood. The VC 2008 *compiler* is not what I am supposed to be using. Solution down 4 posts from here.
 
It looks like VS is still using itself as the compiler instead of VC++ 2003. I recommend that you get the compilation working from the command line to ensure that VS is out of the picture.

Open a cmd.exe window using Run... and switch to the folder holding the makefile. Add VC++'s bin to your path and type "nmake Final_Release". Actually, I'd remove all the .obj and .lib (if there) files first. This can normally be done using one of the clean targets, but IIRC the makefile doesn't have this set up correctly.

When Alerum68 was trying to get it to work in VS 2008 which is what I use, he couldn't get it to use VC++ for the compilation. He ended up moving to Code::Blocks which actually does the compilation itself, and it seems to work for him.
 
The only compiler on my machine is VS9, aka VC++ Express 2008. So when you say "VS is still using itself as the compiler instead of VC++ 2003", I am not able to understand. There is no way it can use VC++ 2003, since that has been obsolete for 5+ years and I do not have it installed.

It isn't clear to me how going to the directory in a command window and executing "nmake Final_Release" will do anything different, since refar's guide instructs me how to set the IDE command line to "nmake Final_Release".

Nonetheless, I tried this, and got an error which I do not understand:
Spoiler :

C:\Documents and Settings\Dave\My Documents\civ-local\try1\CvGameCoreDLL>nmake F
inal_Release

Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.

"C:/Program Files/Microsoft Visual Studio 9.0\VC/bin/cl.exe" /nologo /Z
c:forScope- /MD /Gd /GR /O2 /W3 /EHsc /DWIN32 /DNDEBUG /D_WINDOWS /D_USRDLL /DCV
GAMECOREDLL_EXPORTS /DFINAL_RELEASE /IBoost-1.32.0/include /IPython24/include
/I"C:/Program Files/Microsoft Visual Studio 9.0\VC/include" /I"C:/Program Files/
Microsoft SDKs/Windows/v6.0A/Include" /c CvArea.cpp /FoFinal_Release/CvArea.obj
NMAKE : fatal error U1077: '"C:/Program Files/Microsoft Visual Studio 9.0\VC/bin
/cl.exe"' : return code '0xc0000135'
Stop.


When I choose "build" in the IDE, it executes "nmake Final_Release" which runs successfully for 15 minutes or so, doing lots of compiling, and generates a dll. It just doesn't run because it cannot find msvpc90.dll.
 
This is the disconnect. One of the first steps in Refar's guide is to download and install Visual C++ 2003 Toolkit to do the compilation. It includes cl.exe and link.exe. You also must install Microsoft's Platform SDK which includes nmake.exe. These are the tools that you must use to produce a DLL that Civ4 can work with.

BTW, copy those 3 lib files you downloaded to VC++'s lib folder.

When you set up VS to do your builds, it should be hooking up to those older tools to do the work. All it does is issue the "nmake <profile>" command to them. If you try to compile with the new compiler, you get errors. If you were to fix those and link using the new linker, the EXE won't be able to load the DLL.
 
It seems I completely misunderstood what is supposed to be happening. The compiler to be used is the 2003 one from kael's directory. The only reason to have VC++ 2005 or VC++ 2008 is to have a GUI, which can then execute the nmake command line. To me, at least, this is completely unhelpful. I can execute "nmake Final_Release" from a command line without some big fancy IDE to help me.

I have now successfully compiled a dll which prints "hello world" while saving. Total elapsed time from starting download of the files, a little over 5 hours. Thanks!
 
To be fair to Refar, most of the modders out there have no idea there's a difference between a compiler and IDE and editor. You probably use emacs or vim or something similar that uses ctags. You can already navigate from a function to each of its callers or find all references to a variable without resorting to find-in-file which will give you false positives.

I've done very little "real world" C++ programming. I do Java and Python and slew of other languages, and I tend to use Eclipse because it's a great IDE. But sucks monkey balls at C++. So I use VS because I can easily do all that smart code navigation that is so helpful when learning and navigating a new codebase.
 
I keep getting this fatal error:

Code:
1>NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual C++ Toolkit 2003/bin/cl.exe"' : return code '0x2'

Everything else has been resolved; now, this implies that cl.exe can't be found. However, the file is clearly located in the bin folder...
 
cl.exe is the compiler, so if you saw messages saying each file had been compiled and have files such as CvArea.obj in your Final_Release output folder, it definitely exists. It is in that directory mentioned in the error message. That's a C and an L for CompiLe (though probably not).

Can you post the entire build log as that is usually the final message telling you that some other error occurred. A non-zero return code from a program means "something broke", and the code itself denotes what broke. Unfortunately Microsoft has taken down all the documentation surrounding VC++ Toolkit 2003. :cry:
 
Here. This last rebuild spawned 2047 errors, none of which were due to code. :confused:
 
I have just gotten this to work for me in the past couple of days. Just guessing here, but are you sure that you have the right versions of msvcrt, mscvrtd, msvcprt.lib in the right directory? The link errors seem related to runtime libraries, so that may be the cause. The instructions from refar show the download location and the install directory.
 
I see some errors about using the loop variable iK outside of the loop, yet I know a lot of the Civ code does this, and it works because you're using VC++ 2003. Are you compiling the original SDK files or do they have some changes? If the latter, get the original files compiling first.
 
There are a few changes, but nothing major (just a vassaling tweak)...

Also, re-downloaded the three libraries, put them in the proper folder....still 2047 errors T.T
 
Does refar's makefile actually manage dependencies? For example, cvunit.cpp includes cvinfos.h and cvunit.h. If I change cvinfos.h and cvinfos.cpp, I expect cvunit.cpp to be recompiled because one of its include files changed. If there is a dependency for this in the makefile, I certainly cannot see it.

Do most people do a full clean rebuild after changing any header file? That seems inefficient.
 
No, only the header file of the same name is listed as a dependency which is rubbish. I wrote a Python script that generates the .obj and .lib rules for a makefile by parsing the source, but of course I forgot about transitive dependencies.

I've been meaning to clean it up and post it for others to use. I'll post up what I have now if you want to at least get the main headers included.

Usage: mfMaker.py <target> [ <root> ]

Code:
cd CvGameCoreDLL
mfMaker.py Final_Release

It appends the .obj and .lib rules to the file Makefile as per Refar's example. You'll need to remove the old rules. Eventually I'd like to have it build an entire makefile, but right now my BULL makefile differs considerably from Refar's.

I reorganized it to be a little friendlier. I've included BULL's latest makefile in the ZIP if you'd like some ideas. It's worth a read to see what all the compiler and linker options do. :)
 
Perhaps many C++ programmers have been down this path already, but it is an interesting experiment. I ran makedepend to find all the dependencies and added them to the makefile. However, by counting, I can find that dependencies will never save any time, or hardly ever. There are about 100 source files. Each include file is used in almost all the hundred source files, once you process the transitive references.

So you may as well do a full recompile after any header file change; there is nothing to be saved from carefully managing the dependencies. That is a little disappointing since any header file change will cost about 15 minutes on my machine.
 
I carefully compared your build and link lines to mine. There is one difference. One of my link options is:

/LIBPATH:"C:/Program Files/Microsoft SDKs/Windows/v6.0A/Lib"

Yours is:

/LIBPATH:"C:\Program Files\Microsoft SDKs\Windows\v6.0/Lib/x64"

Also I notice your compiler is installed in "c:\program files (x86)". Is your machine a 64-bit machine? Are you trying to compile a 64 bit object? I doubt that will work. The errors you are getting are linker errors, starting with:

MSVCRT.lib(crtdll.obj) : warning LNK4078: multiple '.CRT' sections found with different attributes (40300040)

I don't understand this particular message, but the point is that the linker is reading your msvcrt.lib and not liking it. Then you are getting a bunch of unresolved references for things which are supposed to be coming from the runtime library.

Do you have a link library path which is exactly the same as mine? Not that mine is special or anything, but I have not made any changes to the install script or makefile, and mine is working.
 
Back
Top Bottom