[BTS] The Easiest Way to Compile a New DLL

Leoreth

Bofurin
Retired Moderator
Joined
Aug 23, 2009
Messages
37,611
Location
風鈴高等学校
In my opinion, it has always been too complicated to set up your system to compile a new DLL for your BtS mod. There are of course great guides on that out there (I want to give a special shout out to asaf's guide that I used to follow), but they still require you to piece together everything from multiple different sources and were in part outdated and not making use of the contributions of other modders since their creations.

I also realised that with Civ4 further aging, it is becoming harder and harder to recreate its development environment, which is getting progressively out of date and obscure. I think we've been in real danger of download links expiring and becoming unavailable.

Also apparently not all distributions of BtS come with the DLL sources. I don't think it should be hard to find those sources.

So I went on to bundle everything you need to set up a DLL compiler from scratch in as few places as possible. This collection is a bit opinionated, for example I settled on Visual Studio and Nightinggale's makefile, but it should run out of the box. Here's the components:

1) A git repository containing the DLL source, all external dependencies (Python and Boost libraries), a Makefile, and a preconfigured project/solution for Visual Studio

2) An ISO file to install Visual Studio 2010 Express

3) An Install Wizard to install the Windows SDK and Visual C++ toolkit


Prerequisites

To download the sources from Github, I suggest you use git, which you can install from here. I suggest using Github Desktop as your git client, which is easy and intuitive to use. In general it is always worth it to familiarise yourself with git as a developer, because even though it initially seems complex and challenging, it really makes your life easier in many ways. You can still download the git repository without installing git, however.

If you want to install Visual Studio from my ISO file, you need a program to mount ISOs. I recommend using the free Daemon Tools Lite.

Setup from Scratch

1) Install the Windows SDK and Visual C++ toolkit


Download the Install Wizard and run it, following the instructions. It will try to install by default to <Program Files>\Civ4SDK\, whatever the name and drive of your primary program files folder is (e.g. C:\Program Files (x86)\). If you choose a different location, please keep note of it for later.

2) Install Visual Studio 2010 Express

Download the ISO File, mount and run it. The installation will also offer to install other tools, but you only need Visual Studio 2010 Express.

3) Get the source code, Makefile and project setup

If you are using git, run "git clone https://github.com/dguenms/beyond-the-sword-sdk.git". Alternatively, you can download it as a ZIP archive from here.

You are downloading the CvGameCoreDLL folder for your new mod. Conventionally, you would put this folder next to the Assets folder in your mod directory, i.e. in Beyond the Sword\Mods\MyMod, and it is preconfigured assuming you do so. Theoretically, you can put it wherever on your computer though.

Depending on your previous choices, you might have to adjust the Makefile in the following ways:
- if you chose a different location during step 1, you have to change lines 34-35 so the TOOLKIT and PSDK variables point to the right locations (remove $(PROGRAMFILES)\Civ4SDK\, and replace it with your chosen location)
- if you did not put the CvGameCoreDLL folder inside your mod directory, put a path to your mod directory into the YOURMOD variable in line 37

4) Launch your project in Visual Studio

Double click on the CvGameCoreDLL.sln file, it should open in Visual Studio with an already configured project.

To test if everything is working, run Build ... -> Rebuild Solution.

Integrating with Git

If you are familiar with Git, you can fork from the BtS SDK source repository right away before cloning it. This way you can commit all your changes as your mod develops, and have everything under source control.

Future Plans

I have several ideas about how to go from here, including:

1) Follow Nightinggale's instructions about optimising file headers for faster compilation time.
2) Set up a build server for the source repo. I think I can configure it in such a way that whenever you create a pull request against the repo, it will build the DLL based on those sources and upload it somewhere. This would actually enable people to run builds without ever setting up a compiler on their system.

Acknowledgements

asaf for his comprehensive DLL modding guide, which I reverse engineered and condensed here
Nightinggale for the included Makefile
 
Last edited:
Thanks for testing!
 
EDIT: Nevermind, figured it out.
 
Last edited:
Thank you so much ! : your tutorial is reliable, very up to date, and very easy to follow. Thank to you, i could work again on my mod.
 
Thanks a lot for the guide, just a quick addition, since I ran into this problem today:

One might encounter the following error, which prevents a successful build: "Error 1 fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt LINK"

A solution can be found following this link: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/391305.

The important post is the last one, which states "Just overwrite $VCDIR/bin/amd64/cvtres.exe in VS2010 dir with C:/Windows/Microsoft.NET/Framework64/v4.0.30319/cvtres.exe and overwrite $VCDIR/bin/cvtres.exe in VS2010 dir with C:/Windows/Microsoft.NET/Framework/v4.0.30319/cvtres.exe."

I did not have the 64 folders, but just doing the second part fixed the problem for me.
 
Thanks a lot for the guide, just a quick addition, since I ran into this problem today:

One might encounter the following error, which prevents a successful build: "Error 1 fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt LINK"

A solution can be found following this link: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/391305.

The important post is the last one, which states "Just overwrite $VCDIR/bin/amd64/cvtres.exe in VS2010 dir with C:/Windows/Microsoft.NET/Framework64/v4.0.30319/cvtres.exe and overwrite $VCDIR/bin/cvtres.exe in VS2010 dir with C:/Windows/Microsoft.NET/Framework/v4.0.30319/cvtres.exe."

I did not have the 64 folders, but just doing the second part fixed the problem for me.
That looks wrong. The compilation should be done with MSVC 2003. It looks like you mixed 2003 and 2010, which is very bad for memory allocations and should never be done unless you really know what you are doing (and even then, try to avoid it). The exe use memory allocation for 2003, meaning we are stuck with the 2003 compiler. Visual studio itself can't use a different compiler, but disabling the compiler and relying on the makefile gets around that problem, providing you use the correct setup.
 
That looks wrong. The compilation should be done with MSVC 2003. It looks like you mixed 2003 and 2010, which is very bad for memory allocations and should never be done unless you really know what you are doing (and even then, try to avoid it). The exe use memory allocation for 2003, meaning we are stuck with the 2003 compiler. Visual studio itself can't use a different compiler, but disabling the compiler and relying on the makefile gets around that problem, providing you use the correct setup.
I can only speculate here, since I am not very used to the whole Visual Studio stuff, but isn't that what Leoreth has set up? I get the "Microsoft Visual C++ Toolkit 2003" with the Install Wizard and VS 2010 with the ISO file. The CvGameCoreDLL.sln file will open VS 2010, and in the makefile we have this line of code:
Code:
TOOLKIT=$(PROGRAMFILES)\Civ4SDK\Microsoft Visual C++ Toolkit 2003
So both 2010 and 2003 are in use, correct?

The only things I did myself was wrongly installing Visual Basic first, which could not work with my vcproj file, but Visual C++ could, and renaming the paths in the lines 34,34 and 37.

As I said, I am able to compile fine now. Takes one or two minutes, don't know if that could be quicker, but since I am not doing that much with the dll anyhow it is fine with me.
 
I didn't set up anything, I just compiled some resources, mostly Nightinggale's Makefile and its dependencies for compiling. Not to avoid responsibility, but you are already talking to the most knowledgeable person here.
 
As I said, I am able to compile fine now.
If you don't end up with weird issues, then it's probably ok. It doesn't feel right to me, but given the situation, it's likely "don't fix it if it ain't broke" kind of setups.

Takes one or two minutes, don't know if that could be quicker
This highly depends on your hardware and mod (not all DLL modifications compile equally fast). I have seen both 30 seconds and 7 minutes as well as various numbers in between (different computers obviously). 1-2 minutes sounds about right for most computers used today. Do note that the targets with a -fast suffix will use all CPU cores, which will often cut the compile time in half, at least for my tests with 4 cores and hyperthreading. More cores will naturally be faster.
 
I have an AMD Ryzen 5 1600 Six-Core processor, but the performance might be a bit reduced since I still cannot let go of Win7. So yeah, the Visual Studio setup might not be optimal, but I am okay with as it is for now.

Also thanks again to both of you. Without this guild and the resources it works with, I certainly would have had a harder time modifying my old core file some more.
 
I got the following error. What am I doing wrong?

1> Linking DLL
1>temp_files\Release\CvGameCoreDLL.res : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt
1>NMAKE : fatal error U1077: '"C:\Program Files (x86)\Civ4SDK\Microsoft Visual C++ Toolkit 2003\bin\link.exe"' : return code '0x475'
1> Stop.
1>LINK : fatal error LNK1141: failure during build of exports file
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command "set TARGET=Release
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.MakeFile.Targets(38,5): error MSB3073: nmake source_list /NOLOGO
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.MakeFile.Targets(38,5): error MSB3073: nmake fastdep /NOLOGO
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.MakeFile.Targets(38,5): error MSB3073: nmake dll /NOLOGO" exited with code 2.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
 
Very nice!
 
Several people have asked if they can use Visual Studio 2017. The answer is yes and I would actually recommend it. 2017 can read 2010 project files meaning there shouldn't be a setup issue when upgrading.

In fact you can use pretty much whatever you want. In fact what needs to be done is calling the makefile from cmd.exe with the right arguments. The project files contains all the commands preconfigured, but nothing is stopping you from adding those commands manually in cmd.exe or in some other IDE if you really want to. Visual Studio has the benefit of using the already configured files, which is why that's the solution I will recommend unless you know what you are doing.

An example of the commands to compile:
Code:
set TARGET=Release
nmake source_list /NOLOGO
nmake fastdep /NOLOGO
nmake precompile  /NOLOGO
bin\jom build
There is one such list for compile, rebuild and clean for each of the 4 targets (Assert, Debug, Profile, Release). There are also versions not using jom as it is more compatible, but only jom will use all cores (nmake is single core) and jom doesn't support Debug or Profile due to how MS handles debug symbols. Granted this isn't trivial to set up, but it's not unreasonably hard either for people who are so much into programming that they want to use a different IDE than the default one.
 
im running with this, and can compile, but getting a lot of errors that i would love to fix ;):


upload_2019-2-16_21-49-16.png


my makefile:

Code:
#### Civilization 4 SDK Makefile 2.5 ####
####  Copyright 2015 Nightinggale    ####
#########################################
#### Civilization 4 SDK Makefile 2.0 ####
####  Copyright 2013 Nightinggale    ####
#########################################
#### Civilization 4 SDK Makefile 1.0 ####
####  Copyright 2010 Danny Daemonic  ####
#########################################


## User setup
##
## Any setting here can be overwritten by assigning a new value to the variables in Makefile.settings
##  Makefile.settings is made automatically if it is missing whenever the project is build or cleaned
##
## Not touching the makefile itself can be beneficial if the makefile is committed to svn/git
## Makefile.settings can also accept CUSTOM_CFLAGS and CUSTOM_LDFLAGS if you want to ADD additional flags
##   the custom flags will not overwrite any flags the makefile sets itself
##   An example could be you want to define ENABLE_MY_DEBUG_OUTPUT in C+, then you write
##     CUSTOM_CFLAGS -DENABLE_MY_DEBUG_OUTPUT
##     in Makefile.settings and it will be defined for you without the risk of committing active debug output to other people
##
##     You can write whatever you want after -D and it will work like you write #DEFINE in C++
##


#### Paths ####
#
# Note: $(PROGRAMFILES) converts to "C:\Program Files", "C:\Program Files (x86)" or whatever fits your system.
# run "nmake.exe /P" in cmd.exe to see what it is on your system
# The MS Visual C++ Toolkit and MS SDKs need to be downloaded separately
# Replace with the correct paths for your system
TOOLKIT=C:\Dev\Microsoft Visual C++ Toolkit 2003
PSDK=C:\Dev\WindowsSDK
## Uncomment to have newly compiled dlls copied to your mod's Assets directory
YOURMOD=D:\Games\Civilization IV Complete\Civ4\Beyond the Sword\Mods\VIP

## Civ install path
## Path to the directory where boost and python is stored
## Overwritten by enviroment variable CIV4_LIB_INSTALL_PATH
CIV4_PATH=D:\Games\Civilization IV Complete\Civ4\Beyond the Sword\CvGameCoreDLL

#### Tools ####
CC="$(TOOLKIT)\bin\cl.exe"
CPP="$(TOOLKIT)\bin\cl.exe"
LD="$(TOOLKIT)\bin\link.exe"
RC="$(PSDK)\bin\rc.exe"
## Uncomment to build dependencies using fastdep
## Overwritten by enviroment variable FASTDEP_FULL_PATH
FD="bin\fastdep.exe"

#### BLACKLIST ####
## Uncomment to block CvTextScreen (accidentally included by Firaxis)
BLACKLIST=CvTextScreens

#### DEFINES ####
## copy the following lines into "Additional options" in NMAKE properties
## This will make VC++ aware of what is defined and what isn't, which affects the help popup and red lines
## Use Release_DEFINES for all targets except debug
## Assert adds /DFASSERT_ENABLE, which should be added to additional options too, if you care.
## However you will only be able to tell a difference if you do something with asserts other than FAssert() or FAssertMsg()

Debug_DEFINES=/DWIN32 /D_WINDOWS /D_USRDLL /DCVGAMECOREDLL_EXPORTS /D_DEBUG
Release_DEFINES=/DWIN32 /D_WINDOWS /D_USRDLL /DCVGAMECOREDLL_EXPORTS /DNDEBUG /DFINAL_RELEASE

#### You shouldn't need to modify anything beyond this point ####
#################################################################

TEMP_FILE_DIR = temp_files
CUSTOM_CFLAGS  =
CUSTOM_LDFLAGS =



!IF [IF NOT EXIST Makefile.settings EXIT 1] != 0
!IF [ECHO CUSTOM_CFLAGS = > Makefile.settings]
!ENDIF
!ENDIF
!include Makefile.settings

PRECOMPILE_DEPENDENCIES =
PROJECT_CFLAGS =
PROJECT_LDFLAGS =
SOURCE_DIR =

SUBDIRPATH1 = ../
SUBDIRPATH2 = ../
SUBDIRPATH3 = ../
SUBDIRPATH4 = ../
SUBDIRPATH5 = ../
SUBDIRPATH6 = ../
SUBDIRPATH7 = ../
SUBDIRPATH8 = ../
SUBDIRPATH9 = ../
SUBDIRPATH10 = ../
SUBDIRPATH11 = ../
SUBDIRPATH12 = ../
SUBDIRPATH13 = ../
SUBDIRPATH14 = ../
SUBDIRPATH15 = ../

!IF [IF NOT EXIST Makefile.project EXIT 1] != 0
!IF [ECHO SOURCE_DIR = .>> Makefile.project]
!ENDIF
!IF [ECHO PROJECT_CFLAGS = >> Makefile.project]
!ENDIF
!IF [ECHO PROJECT_LDFLAGS = >> Makefile.project]
!ENDIF
!IF [ECHO PRECOMPILE_DEPENDENCIES = >> Makefile.project]
!ENDIF
!ENDIF
!include Makefile.project

SUBDIRS = . $(SUBDIR1) $(SUBDIR2) $(SUBDIR3) $(SUBDIR4) $(SUBDIR5) $(SUBDIR6) $(SUBDIR7) $(SUBDIR8) $(SUBDIR9) $(SUBDIR10) $(SUBDIR11) $(SUBDIR12) $(SUBDIR13) $(SUBDIR14) $(SUBDIR15)

TEMP_TARGET_FILES = $(TEMP_FILE_DIR)\$(TARGET)

## Environmental path overwrite
!IFDEF CIV4_LIB_INSTALL_PATH
CIV4_PATH=$(CIV4_LIB_INSTALL_PATH)
!ENDIF

!IFDEF FASTDEP_FULL_PATH
FD=$(FASTDEP_FULL_PATH)
!ENDIF

#### Target Files ####
Target_BIN=$(TARGET)\CvGameCoreDLL.dll
Target_BIN_TEMP=$(TEMP_TARGET_FILES)\CvGameCoreDLL.dll

!IF [IF NOT EXIST CvGameCoreDLL.rc EXIT 1] == 0
Target_RESOURCE=$(TEMP_TARGET_FILES)\CvGameCoreDLL.res
!ENDIF

Target_STATICLIB=$(TEMP_TARGET_FILES)\CvGameCoreDLL.lib

Target_LIBDEF=$(TEMP_TARGET_FILES)\CvGameCoreDLL.def

Target_PCH=$(TEMP_TARGET_FILES)\CvGameCoreDLL.pch

Target_PDB=$(TEMP_TARGET_FILES)\CvGameCoreDLL.pdb

Target_OTHER=$(TEMP_TARGET_FILES)\CvGameCoreDLL.exp

!IFDEF IGNORE_CUSTOM
CUSTOM_CFLAGS  =
CUSTOM_LDFLAGS =
!ENDIF

FILE_DEPENDS = $(TEMP_TARGET_FILES)\depends

#### CFLAGS ####
GLOBAL_CFLAGS=/GR /Gy /W3 /EHsc /Gd /Gm- /Fd"$(Target_PDB)" $(CUSTOM_CFLAGS) $(PROJECT_CFLAGS)
Debug_CFLAGS=/MD /Zi /Od /RTC1 $(Debug_DEFINES) $(GLOBAL_CFLAGS)
Release_CFLAGS= /MD /O2 /Oy /Oi /G7 $(Release_DEFINES) $(GLOBAL_CFLAGS)

PRECOMPILE_CFLAGS1 = /Yu"
PRECOMPILE_CFLAGS2 = CvGameCoreDLL.h" /Fp"$(Target_PCH)"

#### LDFLAGS ####
GLOBAL_LDFLAGS=/DLL /NOLOGO /SUBSYSTEM:WINDOWS /LARGEADDRESSAWARE /TLBID:1 /PDB:"$(Target_PDB)" $(CUSTOM_LDFLAGS) $(PROJECT_LDFLAGS)
Debug_LDFLAGS=/INCREMENTAL /DEBUG /IMPLIB:"$(Target_STATICLIB)" $(GLOBAL_LDFLAGS)
Release_LDFLAGS=/INCREMENTAL:NO /OPT:REF /OPT:ICF $(GLOBAL_LDFLAGS)

#### INCLUDES ####
GLOBAL_INCS=/I"$(TOOLKIT)/include" /I"$(PSDK)/Include" /I"$(PSDK)/Include/mfc"

#### boost and python ####

BOOST_LIB_PATH =
!IF [IF NOT EXIST "$(BOOST_LIB_PATH)Boost-1.32.0\libs\boost_python-vc71-mt-gd-1_32.lib" EXIT 1] != 0
BOOST_LIB_PATH = $(SOURCE_DIR)
!IF [IF NOT EXIST "$(BOOST_LIB_PATH)Boost-1.32.0\libs\boost_python-vc71-mt-gd-1_32.lib" EXIT 1] != 0
BOOST_LIB_PATH=$(CIV4_PATH)/
!IF [IF NOT EXIST "$(BOOST_LIB_PATH)Boost-1.32.0\libs\boost_python-vc71-mt-gd-1_32.lib" EXIT 1] != 0
BOOST_LIB_PATH=$(CIV4_LIB_INSTALL_PATH)/
!IF [IF NOT EXIST "$(BOOST_LIB_PATH)Boost-1.32.0\libs\boost_python-vc71-mt-gd-1_32.lib" EXIT 1] != 0
!MESSAGE FATAL ERROR: Failed to locate boost and python
!ENDIF
!ENDIF
!ENDIF
!ENDIF

PROJECT_INCS=/I"$(BOOST_LIB_PATH)Boost-1.32.0/include" /I"$(BOOST_LIB_PATH)Python24/include"
PROJECT_LIBS=/LIBPATH:"$(BOOST_LIB_PATH)Python24/libs" /LIBPATH:"$(BOOST_LIB_PATH)boost-1.32.0/libs/" boost_python-vc71-mt-1_32.lib

INCS = $(PROJECT_INCS) $(GLOBAL_INCS)

#### LIBS ####
GLOBAL_LIBS=/LIBPATH:"$(TOOLKIT)/lib" /LIBPATH:"$(PSDK)/Lib" winmm.lib user32.lib
LIBS = $(PROJECT_LIBS) $(GLOBAL_LIBS)


!IF "$(TARGET)" == "Debug"
!IFNDEF _NMAKE_VER
!ERROR Jom can't be used on Debug builds
!ENDIF
CFLAGS  = $(Debug_CFLAGS)
LDFLAGS = $(Debug_LDFLAGS)
LIBS    = $(LIBS) msvcprt.lib
!ENDIF
!IF "$(TARGET)" == "Release"
CFLAGS  = $(Release_CFLAGS)
LDFLAGS = $(Release_LDFLAGS)
!ENDIF
!IF "$(TARGET)" == "Assert"
CFLAGS  = $(Release_CFLAGS) /DFASSERT_ENABLE
LDFLAGS = $(Release_LDFLAGS)
!ENDIF
!IF "$(TARGET)" == "Profile"
!IFNDEF _NMAKE_VER
!ERROR Jom can't be used on profile builds
!ENDIF
CFLAGS  = $(Release_CFLAGS) /Zi
LDFLAGS = $(Debug_LDFLAGS)
!ENDIF

!IFNDEF CFLAGS
!ERROR Target "$(TARGET)" not supported. Supported targets: Debug Release Assert Profile
!ENDIF

!IF EXIST ($(FILE_DEPENDS))
!INCLUDE $(FILE_DEPENDS)
!ENDIF

#### Targets ####
#################

.PHONY: all clean build precompile Make_Dir fastdep source_list

all: Precompile build

dll: all

clean:
    @IF EXIST "$(TEMP_TARGET_FILES)" RMDIR /s /q "$(TEMP_TARGET_FILES)"
    @FOR %i IN ($(Target_BIN) $(Target_STATICLIB) $(Target_LIBDEF) $(Target_RESOURCE) \
        $(Target_PCH) $(Target_PDB) $(Target_OTHER)) DO @IF EXIST "%i" DEL "%i"

$(Target_BIN): $(Target_BIN_TEMP)
    -COPY "$(Target_BIN_TEMP)" "$(Target_BIN)"

        
build: $(Target_BIN)
!IFDEF YOURMOD
    -COPY "$(Target_BIN)" "$(YOURMOD)\Assets\."
!ENDIF

precompile: Make_Dir Target_unfinished $(Target_PCH)

source_list: Make_Dir
    @ECHO Building source list
    @ECHO SOURCES= \> $(FILE_DEPENDS)
    @FOR %j in ($(SUBDIRS)) DO @(FOR %i IN ($(SOURCE_DIR)\%j\*.cpp) DO @ECHO %i \>> $(FILE_DEPENDS))
    @ECHO.>> $(FILE_DEPENDS)
    @ECHO OBJS= \>> $(FILE_DEPENDS)
    @FOR %j in ($(SUBDIRS)) DO @(FOR /F "delims=." %i IN ('dir /b $(SOURCE_DIR)\%j\*.cpp') DO @ECHO. $(TEMP_TARGET_FILES)\%j\%i.obj \>> $(FILE_DEPENDS))
    @ECHO.>> $(FILE_DEPENDS)

fastdep:
    @ECHO Running fastdep
    @$(FD) --objectextension=pch -q --removepath=$(SOURCE_DIR)\ -O $(TEMP_TARGET_FILES) $(SOURCE_DIR)\CvGameCoreDLL.cpp >> $(FILE_DEPENDS)
    @$(FD) --objectextension=obj -q --removepath=$(SOURCE_DIR)\ -O $(TEMP_TARGET_FILES) $(SOURCES) >> $(FILE_DEPENDS)

Make_Dir:
    @FOR %j in ($(SUBDIRS)) DO @(IF NOT EXIST "$(TEMP_TARGET_FILES)\%j\." MKDIR "$(TEMP_TARGET_FILES)\%j")
    @IF NOT EXIST "$(TARGET)\." MKDIR $(TARGET)

Target_unfinished:
    @ECHO.>$(TEMP_TARGET_FILES)\unfinished.@
    @FOR /F "delims=@" %i IN ('dir /b $(TEMP_TARGET_FILES)\*.@') DO \
        @IF EXIST "$(TEMP_TARGET_FILES)\%i" DEL "$(TEMP_TARGET_FILES)\%i"
    @FOR /F %i IN ('dir /b $(TEMP_TARGET_FILES)\*.@') DO \
        @IF EXIST "$(TEMP_TARGET_FILES)\%i" DEL "$(TEMP_TARGET_FILES)\%i"

$(Target_BIN_TEMP): $(OBJS) $(Target_RESOURCE)
    @ECHO.Linking DLL
    @$(LD) /out:$(Target_BIN_TEMP) $(LDFLAGS) $(LIBS) $(OBJS) $(Target_RESOURCE)

{$(SOURCE_DIR)\.}.cpp{$(TEMP_TARGET_FILES)\.}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"
    
{$(SOURCE_DIR)\$(SUBDIR1)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR1)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH1)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR2)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR2)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH2)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR3)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR3)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH3)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR4)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR4)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH4)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"
    
{$(SOURCE_DIR)\$(SUBDIR5)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR5)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH5)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR6)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR6)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH6)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR7)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR7)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH7)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR8)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR8)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH8)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"
    
{$(SOURCE_DIR)\$(SUBDIR9)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR9)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH9)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR10)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR10)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH10)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR11)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR11)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH11)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR12)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR12)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH12)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR13)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR13)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH13)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR14)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR14)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH14)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"

{$(SOURCE_DIR)\$(SUBDIR15)}.cpp{$(TEMP_TARGET_FILES)\$(SUBDIR15)}.obj:
    @ECHO.>"$*.obj.@"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(SUBDIRPATH15)$(PRECOMPILE_CFLAGS2) $(INCS) /Fo$*.obj /c $<
    @DEL "$*.obj.@"
    

$(Target_PCH) $(TEMP_TARGET_FILES)\_precompile.obj: $(PRECOMPILE_DEPENDENCIES)
    @ECHO.>"$(Target_PCH).@"
    @ECHO.>"$(TEMP_TARGET_FILES)\_precompile.obj.@"
    @FOR %i IN ($(TEMP_TARGET_FILES)\*.obj) DO @IF EXIST "%i" DEL "%i"
    @$(CPP) /nologo $(CFLAGS) $(PRECOMPILE_CFLAGS1)$(PRECOMPILE_CFLAGS2) $(INCS) /YcCvGameCoreDLL.h /Fo"$(TEMP_TARGET_FILES)\_precompile.obj" /c $(SOURCE_DIR)\_precompile.cpp
    @DEL "$(Target_PCH).@"
    @DEL "$(TEMP_TARGET_FILES)\_precompile.obj.@"

.rc{$(TEMP_TARGET_FILES)}.res:
    @ECHO.>"$*.res.@"
    $(RC) /Fo$@ $(INCS) $<
    @DEL "$*.res.@"

!IFDEF BLACKLIST
$(TEMP_TARGET_FILES)\$(BLACKLIST).obj: $(BLACKLIST).cpp
    @ECHO.>"$*.obj.@"
    @ECHO.>"$*-dummy.cpp"
    @$(CPP) /nologo $(Release_CFLAGS) $(Release_INCS) /Y- /Fo$@ /c "$*-dummy.cpp"
    @DEL "$*-dummy.cpp"
    @DEL "$*.obj.@"

!ENDIF
 
im running with this, and can compile, but getting a lot of errors that i would love to fix ;):
In the error window, select "Build + IntelliSense" and switch it to "Build Only".

The problem is that MSVS compiles your code to get the errors and it's not using the same compiler as the makefile, meaning you get errors for anything working with the makefile, but not the new compiler. Telling the error window to only display errors from Build will force it to only show the errors returned from running the makefile. This is a known issue and not specific to our makefile. In fact the net is full of people with this problem.
 
I am running into a persistent error when trying to compile the dll.
I am getting the following error message:
1>_precompile.cpp
1>c:\Program Files (x86)\2K Games\Firaxis Games\Sid Meier's Civilization 4 Complete\Beyond the Sword\Mods\RFC Greek World 1.24\CvGameCoreDLL\CvGameCoreDLL.h(17): fatal error C1083: Cannot open include file: 'windows.h': No such file or directory

I am assuming one of the file paths is wrong in my makefile, but cannot work out which one.
This is what my makefile looks like:
#### Paths ####
TOOLKIT=C:\Program Files (x86)\Civ4SDK\Microsoft Visual C++ Toolkit 2003
PSDK=C:\Program Files (x86)\Civ4SDK\WindowsSDK
PSDK=$(Civ4SDK)
PSDKBIN=$(Civ4SDK)\bin\x86
#PSDKBIN=$(Civ4SDK)\bin
PSDKINC=$(Civ4SDK)\Include\shared
OTHERINC=$(Civ4SDK)\Include
PSDKLIB=$(Civ4SDK)\Lib
#PSDKLIB=$(Civ4SDK)\Lib\winv6.3\um\x86
CIVINSTALL=C:\Program Files (x86)\2K Games\Civilization 4 Complete\Beyond The Sword
GLOBALBOOST=$(CIVINSTALL)\CvGameCoreDLL\Boost-1.32.0
GLOBALPYTHON=$(CIVINSTALL)\CvGameCoreDLL\Python24
## Uncomment to have newly compiled dlls copied to your mod's Assets directory
YOURMOD=..

## Civ install path
## Path to the directory where boost and python is stored
## Overwritten by enviroment variable CIV4_LIB_INSTALL_PATH
CIV4_PATH=$(PROGRAMFILES)\2K Games\Firaxis Games\Sid Meier's Civilization IV Colonization\CvGameCoreDLL

I am using visual studios 2017 to try and compile it.

Any suggestions for solutions would be gratefully received!
 
Hi @EdmundIronside

Why do you have both:
(1) PSDK=C:\Program Files (x86)\Civ4SDK\WindowsSDK
(2) PSDK=$(Civ4SDK)
The second statement seems redundant.

Unless $(Civ4SDK) is already set to something sensible, it could very well be empty\unset, I would just remove (2), (1) should be correct, assuming that is where your SDK is.
 
Top Bottom