Visual Studio - C++ - build and run app as 32bit or 64bit - load DLL from appropripate ProgramFiles dir - c++

I build my app either as x86 or x64. This app uses external DLL.
I have x64 system (Windows 10) with the same DLL library installed for both platforms - x86 and x64. They are placed in same folders inside appropriate Program Files directory. I can manually set path to either one in environment variable PATH and it woks. But it is a little incovinient to rewrite PATH and reset computer when I switch platform and want to test the other one. Is there any solution, how system automatically loads correct DLL from correct Program Files dir?

I have found solution for running apps from Visual Studio: How do I set the path to a DLL file in Visual Studio?
It is working as epxected. If I run app outise Visual Studio, I set PATH variable by myself and is also working.

Copy the DLL in the build location next to the executable, for Visual Studio this is typically \Debug or \Release in a architecture dependent sub directory (i.e. x86 or x64). Just make sure the target / output locations are set correctly in the project settings.
You have to copy only once, or more correctly: each time after you 'clean' the solution. To make this easier, many people use a dll-copy script (use batch, ruby or python) and have it run automatically before building or after cleaning. You can execute the script in a pre-build step or post-build step that can be configured in your Visual Studio solution or project settings.
There is also a more robust way to handle build artifacts and peculiarities: I highly recommend the use of CMake to keep the build matrix organized. It is provides a general cross-platform approach to script pre-build and post-build actions such as tracking dependencies, copying files, packaging installers, deployment, version verification, versioning, etc.. it comes with an easy scripting language so you can build macro's and functions to do your copying. It can be a bit of a learning curve to get it right, but once it's there, it provides a robust dependable way to build out your project build pipeline.

Related

How to make swapping between Debug/Release less painful in this cross-platform project?

We have a C++ CMAKE project. I work on it under Windows using Visual Studio 2019. My coworkers work under Ubuntu using QTCreator.
Here is what my current steps look like for swapping from a DEBUG build to a RELEASE build:
First set up VTK:
Open the release VTK build folder in Visual Studio and build the "INSTALL" subproject to overwrite the installed debug version of VTK with the release build.
Then set up our project:
Edit my account's PATH environment variable to point to the location of the new sub-project DLLs where Visual Studio will put them. (myProject\lib\analytics\Debug to myProject\lib\analytics\Release)
Without telling Windows where the sub-project's DLLs are, trying to execute the program does not work. Not sure if there's a way to tell Visual Studio to look for the DLLs automatically.
Edit the top-level CMAKE of the project:
SET(BUILD_MODE Release)
set(CMAKE_BUILD_TYPE "RELEASE" CACHE STRING "Sets release build by default")
Open Cmake-GUI and clear the cache, then run "Configure" and "Generate"
If I do not clear the cache, Cmake Gui has consistently used older/incorrect settings resulting in unusual build issues.
Open the project under Visual Studio, changing the build type at the top to my new choice.
Hit "Rebuild" on ALL_BUILD.
With all those steps done, I have managed to swap from a Debug to a Release build.
Is there some way to simplify this process and make it easier to swap between the two?
I am not very familiar with Visual Studio or Cmake, so I'm not sure what functionality I'm missing out on.
There should be no need to change reconfigure the cmake, project when using a multi configuration generator. This of course assumes that the VTK package provides imported targets via find_packag(VTK) that properly work with different configurations. You should be able to verify this by checking the import libraries for different configurations of one of your targets in Visual Studio: there are different import libs for the Release and Debug configurations, you're good to go.
As for enabling your program to find the dlls depending on the confiruation, when using the "Play Button" (Visual Studio Debugger):
You should be able to use generator expressions to modify PATH variable in the environment depending on the configuration.
The following assumes the dlls are located in .../lib/<vtk_component_name>/(Debug|Release) directories.
# should evaluate to "C:/Users/..../buildarea/.../lib"
# Note: it's very likely find_package(VTK) already provides necessary info
set(VTK_BASE_DIR "...")
set(VTK_PATH "")
foreach(VTK_COMPONENT IN ITEMS
data-manager
execution
...
)
# use vtk Release configuration for everything but the debug config
set(VTK_PATH "${VTK_BASE_DIR}/${VTK_COMPONENT }/$<IF:$<CONFIG:Debug>,Debug,Release>;${VTK_PATH}")
endforeach()
set_target_properties(my_exe PROPERTIES
VS_DEBUGGER_ENVIRONMENT "PATH=${VTK_PATH}$ENV{PATH}"
)

Building a Qt executable in Visual Studio 2017

I made a Qt Application in Visual Studio and it works when I run it in the program. However then I build the solution and try to run the executable errors pop up that certain .dll files are not found(QtWidgets.dll, QtCore.dll,QtCored.dll etc.). How can I fix this?
To make your application ready for deployment, you can use windeployqt.
It is a commandline program that comes with Qt and collects all the required dependencies of your executable. Go to your QTDIR/bin/ folder and run this command
windeployqt <path-to-app-binary.exe>
It will scan your binary and copy everything that is needed next to it. For further details, have a look at the documentation.
Well, you have two options:
If you want to distribute your application, you have to copy the required DLLs to the folder where your executable is. You can do this either by copying them manually or you write a script for this. The DLLs are in the binary folder of your Qt installation, e.g.
Qt\5.12.2\mingw73_64\bin
Add the above mentioned folder to your system PATH variable, then the DLLs should be found by your application.

Replacement for CMake

I'm using CMake into build rules in visual studio to preprocess my files before submitting them to the compiler but my customers don't like it.
Is there any CMake alternative or method to preprocess my files and having them integrated into visual studio?
As I understand the question you are using CMake to generate files consumed by a VS project that you created by hand. For whatever reason your customers of your VS project don't like CMake. Presumably you have wired this up by creating custom build steps that invoke CMake to generate the files in your project, either as Build Events on the project, or as custom build steps on various files in the project, such as the inputs to the scripts.
VS lets you run any arbitrary set of commands as part of a Build Event or a Custom Build Step. So you could replace CMake with a suitable script or custom executable written by yourself. It is hard to be specific without knowing exactly what about CMake isn't appealing to your customers.
You can use JavaScript through Windows Script Host to create fairly complex scripts that process custom build steps. They can take command-line arguments, access the file system, etc. For some reason WSH JavaScript is a big secret among most developers and they think that all they have available to them in Windows out-of-the-box are DOS batch files and power shell scripts. JavaScript has been shipping for over 10 years as part of the OS and you can debug the scripts in Visual Studio's script debugger, which is very nice.

Handling images and sound files for a simple C++ project in Visual Studio

I am new to Visual Studio, and I am trying to figure out the best way to organize my projects.
I am writing an application using the sfml library, and I have various resources (images/sounds) that I am using. I dropped these into the project folder, and everything works fine when I launch my application from Visual Studio.
I am wondering though, how does this translate to when a program is deployed? If I go into my solution's debug folder, and try launching the exe, it is unable to locate any of the resource files. Am I suppose to tell Visual Studio to copy files to an appropriate directory, and if so how?
Thanks for any advice or links.
For slightly more complicated "deployment" scenario, you can use post-build scripts to copy the correct files into the output directory and even package it into a zip file, for example.
If you find yourself writing more than one page of batch you may want to consider the options below, because batch is a PITA to debug.
Recent MSVS project files are actually MSBuild files (just open the .vcxproj file in Notepad or Vim). For instance you can use the Copy task, invoke arbitrary programs using the Exec task, etc. It can be a bit more sophisticated than the batch script in post-build scripts. MSBuild 4 can use Property Functions making it quite expressive. Useful reference if you do this
For a "full blown" project, you'll want to roll a dedicated build system using a dedicated MSBuild file, NAnt or even higher level wrappers like Rake.
As a less popular alternative, in a previous project I built a small dedicated "builder" .exe project in the solution and have other projects depend on it. Then in the post-build scripts of the other projects I just invoke the builder projects with arguments to make it perform certain tasks. The advantage is that you can write C# (or F# or VB.NET) and not have to fight the build system (as much) and I think it works quite well for small-mid sized projects.
for my project, I direct everything into one directory.
Go to ur project configuration, change General->Output directory, General->intermediate directory, and Debugging->Working directory to one directory. The reason you cannot locate the resource files is because the debug directory is not the same as the output directory.

Teamcity and register dll

I'm trying to build a project with TeamCity Professional 6.5.2
I have a MVC Visual Studio 2010 project using a visual foxpro dll.
The build fails because the dll is not registered.
How can I register that dll in the build machine, as part of the build process?
Thanks!!
There are two different scenarios Rodrigo, your scenario will fall into one of these:
Assemblies which can be referenced by the project: Wherever possible, include dependent assemblies in your source control repository (the 10th Commandment), usually in a "libs" folder which is referenced by the necessary projects. This centralises all your dependencies, makes it easy for new developers to get started and solves your TeamCity build problem.
Assemblies which need GAC installation: There are times when the assembly simply has to be installed in the GAC (i.e. RightFax). Frankly, the easiest thing to do in this case is just to install the damn thing in the GAC. It's an exception and whilst some people will philosophically argue against it, alternatives can get a bit complex (i.e. automating installation as part of the build), and for money I'd rather invest the time elsewhere.
Installing assemblies on each machine (dev, build, prod) will make future updates and any continuous integration system difficult to maintain in the future.
It would be better to create a folder in your working directory (I call it "Resources") which contains a folder for each group of DLLs. Then you just reference the assembly directly from the Project each time. You get duplicate DLLs across different projects, but it keeps everything very clean and simple.
In Visual Studio 2010 you can download a little utility called NuGut which I believes helps to manage assemblies in a better way.
It is a bad idea to register all DLLs on build agent machine, sometime you can find out that you have to install Visual Studio on a build agent machine, for instance ;)
I would suggest to place such libraries along with your code base in Source Control system (I assume you are using it), and just reference lib's folder by declaring a MSBUild property like
<PropertyGroup>
<LibFolder>$(PathFromCommandLineOrJustHardCodedPath)</LibFolder>
</PropertyGroup>
And then before doing a Build/Compile just copy files from $(LibFolder) into the build $(OutputFolder) using standard MSBuild command Copy by specifying source and destination files, and thats it.
To force TeamCity to pickup Lib (dlls) files from VCS folder just add path mapping into the:
TeamCity Configuration Settings -> Edit Build Configuration -> VCS Root settings -> Client Mapping
EDIT:
In your case looks like you have integration test which depends on external COm Server which you need to launch, so you can programatically registr this DLL, for instance in TestSetup, and then do not forget to unregister it in test TearDown.
Anyway you have to just reference this DLL as
VS Project -> Add Existing Item -> Add as Link
+ set
Copy to Output Directory -> Copy if newer
How-To register COM dll: see this SO post
Finally I added a prebuild event in Visual Studio running the regsvr32 command. The dll was in a known location, so I referenced this way:
regsvr32 /s $(SolutionDir)Lib\ProjDataAccess\ProjDataAccess.dll
Agree with Troy Hunt.
For a Continuous Integration with TeamCity 8.0.2 where you need an assembly (custom made shared assembly) reference from GAC, do the following.
1. Add the assembly to the build pack (In my case its nuget package).
2. Before starting the build process (MSBuild, Visual Studio etc), register the assembly to GAC with the help of a command line build runner.
3. Continue with the build process.
By following the above steps, if you are using MSBuild, the build process can link to a valid reference from GAC, which can produce an expected build result.
In my case, where the code refers a custom component from GAC, MSBuild ignored the assembly reference and completed the build process without an exception. But the deployment with the build output failed. To overcome this situation, I've used the give steps.
Note: It is mandatory that the TeamCity agent needs to run under an elevated user account. Else the addition to GAC won't be permitted and the build process can fail.