1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

[BTS] The Easiest Way to Compile a New DLL

Discussion in 'Civ4 - SDK/Python' started by Leoreth, Dec 29, 2016.

  1. Leoreth

    Leoreth 心の怪盗団 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    33,586
    Gender:
    Male
    Location:
    Leblanc
    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: Dec 31, 2016
  2. magicalsushi

    magicalsushi Prince

    Joined:
    Aug 14, 2006
    Messages:
    571
    Location:
    Oxford, UK
    Brilliant idea! Thank you so much!
     
  3. Dumanios

    Dumanios MLG

    Joined:
    Oct 24, 2008
    Messages:
    4,875
    Simple to follow.

    And all the links work.

    Great guide.
     
    Leoreth likes this.
  4. Leoreth

    Leoreth 心の怪盗団 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    33,586
    Gender:
    Male
    Location:
    Leblanc
    Thanks for testing!
     
  5. Xyth

    Xyth History Rewritten

    Joined:
    Jul 14, 2004
    Messages:
    4,052
    Location:
    Aotearoa
    EDIT: Nevermind, figured it out.
     
    Last edited: Apr 13, 2018
  6. jojoweb

    jojoweb Chimpa-Z

    Joined:
    Jun 6, 2004
    Messages:
    492
    Location:
    Lyon, France
    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.
     
    Leoreth likes this.
  7. SaibotLieh

    SaibotLieh Emperor

    Joined:
    Sep 25, 2009
    Messages:
    1,470
    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.
     
  8. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,308
    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.
     
  9. SaibotLieh

    SaibotLieh Emperor

    Joined:
    Sep 25, 2009
    Messages:
    1,470
    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.
     
  10. Leoreth

    Leoreth 心の怪盗団 Moderator

    Joined:
    Aug 23, 2009
    Messages:
    33,586
    Gender:
    Male
    Location:
    Leblanc
    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.
     
  11. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,308
    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.

    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.
     
  12. SaibotLieh

    SaibotLieh Emperor

    Joined:
    Sep 25, 2009
    Messages:
    1,470
    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.
     
  13. Bonapartist

    Bonapartist Chieftain

    Joined:
    Aug 5, 2012
    Messages:
    16
    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 ==========
     
  14. devolution

    devolution Prince

    Joined:
    Oct 7, 2016
    Messages:
    368
    Gender:
    Male
    Location:
    Stavanger, Norway
  15. Chazcon

    Chazcon Prince

    Joined:
    Feb 16, 2006
    Messages:
    475
    Location:
    Left Coast
    Very nice!
     
    Leoreth likes this.
  16. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,308
    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.
     
    Leoreth likes this.
  17. vincentz

    vincentz Programmer

    Joined:
    Feb 4, 2009
    Messages:
    3,555
    Gender:
    Male
    Location:
    Denmark
    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
    
    
     
  18. Nightinggale

    Nightinggale Deity

    Joined:
    Feb 2, 2009
    Messages:
    4,308
    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.
     
    vincentz likes this.
  19. EdmundIronside

    EdmundIronside Prince

    Joined:
    Jun 27, 2017
    Messages:
    367
    Gender:
    Male
    Location:
    Grand Rapids, MI.
    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!
     
  20. devolution

    devolution Prince

    Joined:
    Oct 7, 2016
    Messages:
    368
    Gender:
    Male
    Location:
    Stavanger, Norway
    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.
     

Share This Page