Author Topic: Debugging custom mission DLLs  (Read 15322 times)

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Debugging custom mission DLLs
« on: February 23, 2016, 09:36:54 PM »
I updated and expanded this example and placed it on the new wiki here: http://wiki.outpost2.net/doku.php?id=op2_sdk:projectsettings.

The example lists common development environment customizations when creating Outpost 2 scenario DLLs using Visual Studio. The customizations include changing the target file name, copying files to a new directory on post build, referencing Outpost 2 from Visual Studio, and debugging.

Please note, my original post below is a little inaccurate since you do not have to copy the PDB file to the Outpost 2 directory for debugging. The article linked to the Wiki explains this correctly.



Just wanted to share something I learned today which may be common knowledge for a lot of programmers, but it was new to me!

It is possible to run debug software on mission DLLs that you can compile even though we do not have the Outpost 2 source code. The bad news is, you can only debug the DLL that you compile and not Outpost 2, so unless you can catch your mistake inside the DLL, it isn't helpful.

I was surprised how easy it was to setup the debugging. The example below is using Microsoft Visual Studio 2015 Community Edition, although I bet a lot of other IDEs can accomplish the same thing.

Step 1.
Have a Visual Studio solution and associated custom mission DLL you want to debug. (of course!)

Step 2.
Add the Outpost 2 executable as an existing project to your Visual Studio Solution.

File -> Add -> Existing Project -> Select Outpost2.exe (from wherever it is installed on your machine)

You should see Outpost 2 as a second project in your solution explorer after this.



Step 3.
Set Outpost 2 as the StartUp Project by right clicking on it in the solution explorer.



Step 4.
Compile your DLL. Locate your DLL and the associated .PDB file (Program Debug Database). The PDB file should be named the same thing as your DLL. Paste both of these files into your Outpost 2 root directory as if you were going to use them to play the game (Also include other requirements like the .MAP file and tech tree .TXT file as needed).



Step 5.
Inside Visual Studio, set a break point where you want to examine the code.

Step 6.
From Visual Studio press Start Debugging (or hit F5). Outpost 2 should load normally. Once Outpost 2 accesses your DLL, Visual Studio should pause the program at the break point and let you examine the stack trace.

« Last Edit: October 12, 2016, 04:14:08 PM by leeor_net »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #1 on: February 24, 2016, 10:58:11 PM »
Thank you for this.

I've often set a reference to the Outpost 2 executable file to quickly load up the game for testing purposes, but I've never actually used the Visual Studio debugger in that manner before.

Do you really need to copy the debug information to the Outpost 2 folder?

To copy the DLL and map files to the Outpost 2 folder, you can set a post-build step. I generally only do it for the DLL file though, since that's the one that changes, and because I don't make maps or tech tree files.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #2 on: February 25, 2016, 09:09:25 PM »
Hooman,

Thank you for the pointers. I just checked and visual studio is happy debugging the DLL even if the pdb file is not present in the Outpost 2 directory, as long as the pdb file exists in the normal post build directory of the Visual Studio project.

I looked up how to setup a post build event today to copy the DLL into my Outpost 2 directory and it was surprisingly easy.

I'm considering writing a new post called streamlining custom map testing or something and going over how to set a target name separate from the project name for the dll, the info I posted here about debugging, and setting up a post build copy event.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #3 on: February 25, 2016, 11:01:30 PM »
That would actually be good to summarize. When upgrading project files to new versions of Visual Studio, those are the things that need to be taken care of. It's particularly relevant when jumping too many versions away, so the project files need to be recreated.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #4 on: February 27, 2016, 11:04:23 AM »
I decided to make the tutorial on the Wiki, partly because I could insert more than 4 images. You can see it here:  http://wiki.outpost2.net/doku.php?id=op2_sdk:projectsettings.

I also edited the first post in topic to reflect new location.

If anyone has any feedback, suggestions, or corrections, please let me know and I'll update.
« Last Edit: October 12, 2016, 04:13:35 PM by leeor_net »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #5 on: February 29, 2016, 01:00:43 AM »
Well written. There are a few things I did a little bit differently.


For the post build step, I use the $(TargetPath) macro, which includes the path, filename, and extension, all in one macro.
Code: [Select]
copy $(TargetPath) ..\..\..\..\GameDownload\Outpost2\trunk\

Since you changed the output filename in the project settings, you can omit the destination filename, and just provide a destination folder. I didn't rename the project output filename so I included a destination filename to do the rename during the copy.
Code: [Select]
copy $(TargetPath) ..\..\..\..\GameDownload\Outpost2\trunk\ml4Hoo.dll


I didn't add Outpost2.exe as a project in my workspace/solution. Instead, I set Outpost2.exe as the startup executable for the DLL project. You get the same benefit of easily launching Outpost2.exe when you want to run or debug your level.


I added the Outpost2DLL and OP2Helper projects to my workspace/solution, and set the level DLL project to depend on them. Any changes to SDK projects would then cause the level to be rebuilt as well. That aspect is mostly helpful for people actually working on the SDK files, but still useful when an SDK update is downloaded. What's more widely beneficial is being able to easily open and browse SDK header files, since the projects are right there in the workspace/solution.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #6 on: February 29, 2016, 02:19:47 PM »
Hooman,

Thanks for reviewing. It never occurred to me that a repository copy of the game could be used for development. I added another paragraph to the article capturing this. See below.

So, I understand the benefit of referencing the actual Outpost2DLL and OP2Helper projects. However, what if someone prefer a stable API that isn't being updated and possibly broken in the short term by someone else? Would it be acceptable to link to Outpost2SVN\LevelsAndMods\tags\SDK-V2 instead for stability?

I'm unsure how you are setting Outpost2.exe as the startup executable for the DLL project. Is this a setting under the properties of the DLL project? Having difficulty finding it.

Addition to article
If placing a project into the Outpost2SVN, copy your output files into the repository's Outpost 2 game folder using a relative path. This allows post build events to work on other computers where the repository is downloaded without changing the destination of post build event copies.

  • See the Outpost 2 game on the repository located at Outpost2SVN\GameDownload\Outpost2\Trunk.
  • For an output path example, use a path similar to ..\..\..\..\GameDownload\Outpost2\trunk\.

----
Modified to fix errors noted by Hooman.
« Last Edit: March 03, 2016, 09:18:04 AM by Vagabond »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #7 on: March 01, 2016, 03:46:44 AM »
Looks like you have a path typo: "Outpost2SVN/GameDownload/Trunk", doesn't match "GameDownload\Outpost2\trunk\"

The extent of the SDK updates are very minimal. Mostly just adding missing parameter names, or updating them for clarity. Such changes don't affect source code compatibility. It's more of a documentation change. The biggest changes that get made are project layout changes, but that tends to affect the sample projects rather than the SDK. OP2Helper could get some additions, but additions shouldn't affect compatibility. You could of course work with a tagged version if you want. I don't think there is a need.

Quote
I'm unsure how you are setting Outpost2.exe as the startup executable for the DLL project. Is this a setting under the properties of the DLL project? Having difficulty finding it.
It is set on the DLL project, under debug settings. Set it to start an external executable.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #8 on: March 03, 2016, 09:16:02 AM »
I finally managed to set an external executable for debugging. Below are the exact directions pulled from MSDN for VS 2015 (I'm a little dense sometimes and needed step by step instructions for this one).

1.   In Solution Explorer, select the project that creates the DLL.
2.   From the View menu, choose Property Pages.
3.   In the Property Pages dialog box, open the Configuration Properties folder and select the Debugging category.
4.   In the Command box, specify the path name for the container. For example, C:\Program Files\MyApplication\MYAPP.EXE.
5.   In the Command Arguments box, specify any necessary arguments for the executable.

Fixed the path typos Hooman pointed out. I just noticed all this information is available in the ReadMe file at the root of Levels directory in the repo. I should review the ReadMe files more often.

I am learning that you can add Visual Studio 2010 projects to a Visual Studio 2015 solution. You just have to go into the properties of the older project you add and change the Platform Toolset to from Visual Studio 2010 to Visual Studio 2015 and it will compile.If you have the Visual Studio 2010 toolset installed, you could probably just add the project and not change any properties.

Well, this topic seems to have become thoroughly derailed, but I learned a lot in the process of derailing it.  :-\

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #9 on: March 04, 2016, 12:51:08 PM »
Hah

Well, I bet you learned a lot more from the experience than you ever could have learned from that ReadMe file.  :P

It would be nice to have everything standardised on the latest version. And really all of this is quite on topic when you consider it's all about optimizing a compile and debug workflow.


Edit: It might be a good idea to update the ReadMe file with your new findings and version changes.
« Last Edit: March 04, 2016, 01:00:33 PM by Hooman »

Offline leeor_net

  • Administrator
  • Hero Member
  • *****
  • Posts: 2352
  • OPHD Lead Developer
    • LairWorks Entertainment
Re: Debugging custom mission DLLs
« Reply #10 on: March 17, 2016, 03:31:03 PM »
Standardizing is what I wanted to do but Leviathan kind of said "NO! WE DO IT THE WAY WE ALWAYS HAVE!" so I kind of let it go. Maybe I should just force it.... /me ponders
« Last Edit: March 17, 2016, 03:33:59 PM by leeor_net »

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #11 on: March 27, 2016, 12:59:06 PM »
I wrote up another WIKI article covering Outpost 2 scenario project creations on the wiki: http://wiki.outpost2.net/doku.php?id=op2_sdk:projectcreation.

The article takes someone from a blank project to 80% of required project settings to build an Outpost scenario. It is missing information on Visual Studio 2015 Redistributable requirements, WINE compatibility, and statically linking to code instead of relying on pre-installed DLLs. I think the current community idea is to copy a project scenario template to code a new scenario as opposed to starting with a blank project like this article does. 

Some of the explanation of why settings are required is just plagiarizing what Hooman and Arklon wrote, so hopefully that is okay with everyone.

@Leeor_net,

I think standardizing is a good thing. How solutions and projects are setup will continue to become more important as Outpost 2 ages. With every release of Visual Studio (or any other IDE), they will continue to move away from prescribed coding practices in 1997. It will be difficult for someone wanting to code maps to both tackle the project/compiler settings along with learning the SDK. Especially if they are not already familiar with the C++ language. It also makes helping someone difficult if they do not use the same settings and folder structures as others.
« Last Edit: October 12, 2016, 04:07:51 PM by leeor_net »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #12 on: March 31, 2016, 05:27:31 AM »
Your article is quite substantial. There's lots of good information in there. Thank you for writing it.

As you've brought up, I'd recommend doing an SVN copy of an existing project template to start a new project. It's a quick and easy way to get a new project file with all the right settings, and even preserves history back into the initial project setup. It also encourages people to commit their code to the repository, since it's already setup for a commit, with changes tracked, and diffs available.

For people working with newer versions of Visual Studio, or updating the SDK, your article should be quite helpful. Someone will always need to know this to keep things up to date. I also think it's a great learning exercise to go through that stuff manually at least once, and learn what it all does. At the very least, it makes the SVN copy approach easy to appreciate.


I had a few thoughts while reading through the page.

You used "SVN" in the second title, and I think there may be the occasional lurker who will come by and won't know what SVN is or what it stands for. I'd suggest "Subversion Repository". I like how you linked to the repository wiki page.

It'd be nice to add a small section on starting a new project using SVN copy, and put it just before the section on starting a new project from scratch. A single small paragraph should be enough. There's probably a post that can be linked to if more details are desired. A short mention of righ-click-drag copy-and-rename would be helpful. It's a non-obvious and very handy way of making a copy. A small picture of the shell menu would be golden.

The section on adding references has no explanation why. Most people could skip this step and never know what it was supposed to do. It controls compile order. It is useful for triggering a recompile of your project if you update the SDK projects. It's most useful for people working on the SDK. It will also cause a recompile of the project if a new SDK update is downloaded (perhaps through SVN update). Setting references is just manually declaring dependencies.

For the section on "Build Platform Toolsets", there is reference to the "error below", which is 2 paragraphs below. I think this could be restructured. Perhaps introduce the error message, saying this may occur during a project upgrade (I assume that's when it happens), state the error message, possibly box it off or somehow make it visually stand out, and then explain the reason and solution below. A path to relevant menu options would be helpful here. I'd also like to ask if you've encountered this on level projects, or only on the projects in the API folder? This isn't something I've investigated myself.

A small personal note on the configuration section, is that SDK used to be set to optimize for size over speed. Most DLL code is not run very frequently, and there is little benefit to speed optimizations, but size optimizations can affect DLL size noticeably. I was also in the habit of doing all development in release mode. I'm not actually too clear on what benefits there are to developing in debug mode, but then I've also never tried to set breakpoints in Visual Studio while developing level DLLs. Maybe this topic is worth exploring further. It would be nice to have specific points to give for why one configuration might be desirable over another.

Under the "Base Address Explained" section, I'd suggest the wording "optimizing load addresses" over "optimizing code". Also under this section, I'd suggest rewording the sentence: "By leaving a compiler default, DLLs will tend to conflict with their preferred memory address, causing relocations upon loading". I worded this badly in an earlier explanation. I think it would be more clear to emphasize this is a global problem over the development of many DLLs, where if they're all set to use the same default base address, there will be contention for that address, forcing all but one of the DLLs to be relocated.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #13 on: April 02, 2016, 09:45:09 PM »
@Hooman,

Thanks for the feedback and thorough review. I've started updating the article with the recommendations, but it will take me a few days to finish all of them.

Visual Studio Build Toolset (Error MSB8020)
The Build Platform toolset error occurs when I am using Visual Studio 2015 to make a map and add one of the API projects to my solution. All the API projects are currently set to build with the Visual Studio 2010 Toolset. The only toolset installed standard with Visual Studio 2015 is the 2015 Toolset. I can either change the API project to the newer 2015 toolset or install a copy of the 2010 toolset. If you have both Visual Studio 2010 and Visual Studio 2015 installed, you will not see the error since you have both toolsets installed. It isn't too bad an error since the error code is pretty self explanatory. I'm not sure if Visual Studio would complain if you have both toolsets install and select separate toolsets for each project.

Perhaps we should advertise which is the current standard version of the SDK we are using. I could update the repository projects to use the 2015 toolsets, but then anyone without 2015 would have to switch them back on their local machines when they pull repo changes.

I wonder the toolset version used is tied into which Visual C++ redistributable is required to run the compiled software. I'm betting if I installed and used the 2010 Toolset, it would require the Visual C++ redistributable 2010 instead of 2015. I haven't tested this though. Visual Studio 2015 seems willing to use the 2013 toolsets I have installed from Visual Studio 2013.

Solution Configuration: Debug vs Release
Honestly, I'm setting Debug configuration for debug because that is what Microsoft recommends. I have vague memories of code not stepping through the debugger properly when I was coding in release mode a while ago, but don't remember the specifics. It is an easy fix to just switch to debug mode. I was programming in release mode since that was what everyone else seemed to be doing until I started actually setting breakpoints. Here is Microsoft's recommendation: https://msdn.microsoft.com/en-us/library/wx0123s5.aspx. I don't see any benefit to trying to debug code in release mode (besides checking that it works when fully optimized in release mode I suppose). There may be some difference in compile time when setting release vs debug, but in either case my level DLLs are compiling quickly enough that I'm not worried about it.

I think if you don't plan to step through your code with the debugger, set local variable watches, or other similar things, it probably doesn't matter if someone just codes their entire scenario in Release mode. I didn't find setting breakpoints useful until starting to get a little more abstract with things like the RubbleMaker class where the program was tracing through longer sections of my DLL code before exiting back to the internals of Outpost 2. I also didn't know if was possible to set breakpoints in the DLL while Outpost 2 was running until doing some research. At first I figured you needed the executable's source code, which isn't true.

Some random side notes... I noticed there is a defined a custom solution configuration called ReleaseMinSize on the OP2Helper project. Microsoft actually prohibits distributing software built with the debug solution configuration (although I don't know why you would purposely do this).

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #14 on: April 03, 2016, 03:41:17 AM »
I suspect updating the project files for the API projects will make the toolset error go away. Checking inside Outpost2DLL.sln I see the following text:
Code: [Select]
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010

Also interesting is inside of Outpost2DLL.vcxproj is the text:
Code: [Select]
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

It's the same thing for the OP2Helper project.

Standardizing on the latest version of Visual Studio makes the most sense to me. Particularly since it's a free download.

I'm pretty sure the toolset is tied in to what redistributable package is needed to run the code. If you do a static compile though, it won't depend on the external redistributable libraries, so it shouldn't matter. Maybe we should just set the example projects to statically link the CRT. I doubt the slight increase in size is much of a problem these days. Besides, the tools have gotten better at stripping out unneeded stuff.


You're quite likely right about not stepping through code properly in a release mode. When optimizations are turned on, certain parts of the code can be reordered, merged, or omitted, which complicates stepping through the source view. A debug compile should turn off optimizations, ensuring the assembly code more closely maps to the source code. I don't generally use the debugger to trace code, which is one reason why I haven't bothered with debug builds.

I think older versions of Visual Studio could setup the ReleaseMinSize settings automatically when you asked it to optimize for size. The name is a holdover from the Visual Studio 6 version of the project files. It might be better to just go with the default Release configuration name, and just change the settings to optimize for size over speed. We only ever really used one Release configuration, and it was to optimize for size.

Microsoft supplies a redistributable package for release builds. It doesn't provide a redistributable package for debug builds. Hence you're not supposed to redistribute the Microsoft debug libraries with your code. If your code dynamically links to those libraries, that's a problem for distribution.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #15 on: April 05, 2016, 04:46:17 PM »
I finished making changes to the project creation article. It now recommends creation of a new scenario through svn copy & rename, but still walks through all the steps in case you need to go from scratch. A couple of screenshots were added since the right click and drag can be confusing with Tortoise SVN.

The fixed base load address section reads a little differently. More information on why project references are required is now included. I also amplified the section about Debug/Release configuration to more thoroughly explain when you want to build in DEBUG mode. This section now also discusses considering staying the release configuration if you have no plan to use debug tools on your scenario code.

The section on Build Toolsets now has the error message offset a little as a quote and was restructured for clarity.

The article can be still found here: http://wiki.outpost2.net/doku.php?id=op2_sdk:projectcreation

/fixed Linker Property
I just learned you can force your program to throw an error if it cannot be loaded in its defined fixed base address by using the /fixed property. This could be useful in spotting base address conflicts quickly.

If interested, see https://msdn.microsoft.com/en-us/library/w368ysh2.aspx.

Repository Level Templates
I realized the 3 stock level templates in the repository had ASLR set to on and no base address set. I went ahead and updated the repository. I also set the Build Toolsets to Visual Studio 2015 on the templates. If anyone is using them with older versions of Visual Studio, just set the Toolset back to your version.


@Leeor_net
If you are reading this, the Redmine SDK has a base address specified but also has ASLR set to on. For consistency sake, it would be good to set ASLR (DYNAMICBASE) to off on the Redmine download. I don't seem to have permissions to update. I'm unsure if it will honor the base address with ASLR enabled or what the priority is there.

@Hooman,
I'm still having difficulty removing the Visual C++ 2015 Redistributable dependency from my scenarios. I have Runtime Library set to /MT in the scenario project and all sub-projects, but it still seems to require the pre-requisite on Windows 7. Not sure what else to do here.
« Last Edit: October 12, 2016, 04:05:26 PM by leeor_net »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #16 on: April 06, 2016, 11:49:39 AM »
Thanks for the update.

I noticed in one of the new SVN images, you mention the copy and rename option in the text, but have the move and rename option highlighted.

Steps 8 and 9 are extra to the copy step, although I do like how they are mentioned. Maybe that part and the associated image should go in a separate paragraph below. It's good to encourage people to commit new projects to the SVN.


Thank you for updating the stock projects. It's important the starter template projects stay up to date.

It makes some sense to specify the /fixed option. I'm not sure if I want to recommend that as a default. For a non-fixed DLL, there is a possibility of problems if a DLL gets relocated between save/load. With ASLR turned off though, this should be unlikely. Everything should just always load to the same address, provided nothing else strange happens. It's possible for a DLL to work correctly if it's loaded to a non-preferred address, and to avoid things like the save/load/mission objectives bug, provided the DLL is always loaded to the same non-preferred address. With the /fixed option, the DLL would instead fail to load. For that reason, I think I'd prefer not using /fixed by default. Granted, each DLL that's loaded could have ASLR enabled, and could end up mucking things up if it conflicts with another DLL. Anyone else have an opinion on this option?

What do you mean exactly by having trouble removing the dependency? Have you tried the level on a Windows 7 machine and it gives a load error, and installing the redistributable package fixes it? Are you testing this yourself, or is it user reported? Have you checked the DLLs dependencies with a tool like "depends"? Have you checked all dependent projects and imported libraries? Is there an easy way to reproduce what you're doing that demonstrates the problem? This might actually be a rather interesting problem.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #17 on: April 09, 2016, 09:52:39 PM »
For Visual C++ 2015 Redistributable,

I'm testing it on my wife's Windows 7 computer. She doesn't have any software using the 2015 Redistributable. Without it, Outpost 2 gives an error when trying to play the map. If I install 2015 Redistributable on the machine, the map can run.

I did load the map's DLL into Depends. It is kind of a mess though (more likely a mess because I've never used it before). See attached a screenshot of what depends shows. This is from my development cpu, so the scenario runs fine. When Depends is run from the non-development cpu, it shows issues with VCRUNTIME140.DLL.


For the article, I updated the image to be highlighting copy and rename instead. However, the article is still showing the older image. I think maybe it is a caching issue, but not sure how to force an update. Perhaps in a couple of days it will fix itself... I could rename the file, but I don't have permission to do that.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #18 on: April 11, 2016, 01:21:51 AM »
That's some good debug info. Looks like the DLL is still being compiled to depend on an external Visual Studio 2015 runtime (version 14).

I would assume static linking should be able to fix the dependency issue. I suspect what might be happening is there is a reference to the dynamic version of the runtime in one of the modules being compiled into the DLL. This might be from a dependent project, or a linked in library. Remember that a project can have more than one build setting specified, and changing the build settings of the current project can (or might not) change the version of a dependent project that is used. Check that a release version of the level code doesn't compile against a debug build of the API projects, and the dynamic or static linking options are properly set.

You can perhaps also try the Dumpbin.exe tool to further debug this problem. It comes with Visual Studio, so you should already have it installed. The options that look to be of interest are /DEPENDENTS and /IMPORTS.


As for the caching issue for the wiki update, pressing Ctrl+F5 will usually do a hard refresh in most browsers, forcing a cache reload. The cache may have expired by now though, so just revisiting the page might show the update.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #19 on: April 11, 2016, 07:05:38 PM »
@Hooman,

Thank you for the tips, I think they helped me solve the issue. I had added vcruntime.lib as an Additional Dependency for the Linker, which is certainly why it was still requiring the Microsoft Visual C++ Redistributable.

I've removed the dependency from the attached DLL. It runs without the Redistributable on my wife's computer (Windows 7). It would be nice if you or someone else could give it a quick test in WINE and make sure it is still compatible. I had added it as a dependency to troubleshoot the DLL not working on WINE.

If it works, I'll push it out and the other scenario I made with the change.


The image looks good on my computer now, so must have been a caching issue. Silly of me to post the wrong highlighting item in the first place...

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #20 on: April 15, 2016, 03:22:35 AM »
The level works fine under WINE.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #21 on: April 15, 2016, 05:25:43 PM »
@Hooman,

Thank you for the test. My two scenarios are updated in the repository with the changes. I'll plan to update the Project Creation Article to include a section on dependencies, how to remove them, and mention using Depends to troubleshoot as needed.

I have another scenario basically ready for release but want to playtest it again first. Won't have time until maybe Sunday for that.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #22 on: April 19, 2016, 06:15:38 PM »
Okay,

Update to the Project Creation article on the wiki to include Static/Dynamic Linking to the runtime library. Added info is posted below as well. I wouldn't mind cleaning up a little on the part discussing a Subversion Commit as Hooman mentioned. The article is starting to get a little lengthy now.

As always, please send change recommendations.

Runtime Library Settings

DLLs built in Visual Studio require code from a Microsoft C++ runtime library to operate. Typically, a new version of the runtime library is created when Microsoft ships a new copy of Visual Studio. Required code from the runtime library may either be dynamically linked to (requiring access to the redistributable DLLs), or statically linked to (including the necessary parts of the redistributable DLLs within the new DLL being compiled). Computers that do not have the required version of the Microsoft C++ Redistributable package installed, cannot consume the DLL.

For Outpost 2 scenarios, the recommended setting for linking to the Microsoft C++ runtime is multi-threaded static linking (/MT).

Using dynamic linking for C++ code generation will require a Visual C++ Redistributable package be installed on the computer consuming the DLL. The specific required Redistributable will be determined by the Platform Toolset used to build the project. For example, using the Platform Toolset Visual Studio 2015 (v140) will require the computer to have the Visual C++ Redistributable 2015 installed.

Note: Outpost 2 will not provide a useful error message if a scenario requiring a Microsoft C++ Redistributable package is loaded on a machine that does not have the prerequisite.

Using static linking for C++ code generation will increase the size of the DLL because it is not able to access code from the redistributable package. If future security or performance updates are made to the redistributable package, the DLL will not benefit from the updates without being recompiled.

To change the Runtime Library Settings to static linking (recommended for Outpost 2 scenarios):

  • From the Solution Explorer, right click on the project and select Properties.
  • Ensure Configuration (top left of dialog) is set to Release.
  • Click on C/C++ → Code Generation → Runtime Library.
  • Select Multi-threaded (/MT).
  • If using Debug Mode for code testing, change Configuration to Debug.
  • Select Multi-threaded Debug (/MTd).

Further reading on Runtime Libraries: https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx?f=255&MSPPError=-2147217396

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Debugging custom mission DLLs
« Reply #23 on: April 22, 2016, 11:41:36 PM »
I'm going to suggest a small wording update. As your note about the redistributable package relates to dynamic linking, I'd suggest putting the dynamic link option second, so it's close to the following sentence that further discusses it. Also a slight nitpick, the CRT is copied from the associated .lib file rather than the corresponding .dll file.
Quote
Required code from the runtime library may either be statically linked (including necessary parts within the new DLL being compiled), or dynamically linked (requiring access to the redistributable DLLs). Computers that do not have the required version of the Microsoft C++ Redistributable package installed, cannot use the dynamically linked DLL.

It might be good to give the vague and unhelpful error message so people can recognize it if they see it, and also so they can search for it.
Quote
Outpost 2 will not provide a useful error message if a scenario requiring a Microsoft C++ Redistributable package is loaded on a machine that does not have the prerequisite.

You made me realize something. For changing the runtime library settings, you can probably omit steps 5 and 6 for debug builds. They don't follow in sequence with the other steps, and probably aren't that useful. A debug build shouldn't be distributed, and the person working on the level will have Visual Studio installed, and so will have the necessary dynamically linked debug DLL files (which are not legally "redistributable").

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Debugging custom mission DLLs
« Reply #24 on: April 28, 2016, 02:18:42 PM »
@Hooman,

Thank you for the suggestions. I've made the changes on the article. I also added the error message I was getting when the redistributable wasn't installed but was required.

The only one I didn't agree with was setting the default build for the runtime library. While someone shouldn't redistribute a debug build, I think it is still a good idea to link the debug and release versions the same way whether statically or dynamically to the C++ redistributable. This will keep the dependencies the same between the two different builds. I did combine steps 5 and 6 into one step so it was a little more clear that they were only for if you are using a debug configuration.