Native Makefile alternative for windows - c++

What is a good alternative to Makefile on windows?
I'm compiling a collection of c++ files (.cpp's and .h's) using cl.exe.
I'd rather not use Makefile, as I want to minimise the amount of 3rd party utilities people will need to build my application.
Drew J. Sonne.

VisualStudio comes with nmake which would not require any 3rd party tools.

MSBuild, the Microsoft build system. It's the XML-based build system used by Visual Studio. If you have Visual C++ installed, you have MSBuild installed.
Visual Studio project files are just MSBuild files, so anything you can do in Visual Studio with project files, you can do by hand (or vice-versa; you can build Visual Studio projects on the command line).

I would think that depends on which C++ compilers you are supporting for Windows. If you are exclusively targetting Visual Studio users then simply providing the necessary project files should do the trick as your users can either open them in the IDE or use devenv.exe/msbuild.exe to build your project via the command line. In this case, my suggestion would be to provide the project files for the oldest version of Visual Studio that you support as the newer ones will be able to convert the files to the format they require.
It gets a little more tricky if you are trying to support other C++ compilers for Windows also. Either you'll have to provide project files for all of their IDEs which can be tricky if you don't have access to all of them, or you'll have to go for the lowest common denominator, which would be the simplest Makefile possible and hope that most programmers will have make installed, which isn't an unreasonable assumption.
If your software requires the Boost libraries, another approach would be to provide a set of .jam files as most programmers who have Boost probably have bjam floating around back from when they built Boost. While bjam isn't quite as simple as make, it does have the major advantage that it already knows how to handle multiple compilers. But I would only consider bjam if the software distributed required Boost, otherwise it's another unwanted dependency.

Related

What is the proper way to include a source library in a Visual Studio C++ project?

Right now I'm trying to create my first "real" project in C++ using Visual Studio 2019. I need to include a third-party library as a dependency. The instructions on the project homepage simply recommend to include all source/header files directly into the project. My understanding is that it's a bad practice, since the end result would look quite ugly in any VCS.
Thankfully, the library author also provided build scripts that call cl, lib and link with appropriate arguments and produce the coveted foo.lib. I added that file to dependencies in linker options and after some haranguing with compiler/linker options finally got it running.
To my distress, I realised that I've done all those manipulations in Release configuration, which prevented me from using the debugger. I then built the library with /MDd, fixed some compiler options... and got a bizarre compile-time error in vcruntime.h ( fatal error C1189: #error: _HAS_CXX17 and _HAS_CXX20 must both be defined, and _HAS_CXX20 must imply _HAS_CXX17).
At this point, I knew I was doing something terribly wrong, since including a simple library should't require so much manual knob-tweaking. What is the right, canonical way of including third-party dependencies in Visual Studio (and C++ in general)? Assuming the dependency isn't available on Nuget, vcpkg or somesuch.
As I understand from the stuff you did was on Windows. First of all I would recommend you try a linux distro. In windows it is possible to get lib files running, but not easy. It would help if you could send me a link to the library you are using.
The usual approach is to just stick those sources in their own directory and their own Visual Studio project (not solution). This can still build a foo.lib. You won't need many options for this.
Next, you just tell Visual Studio that your own project depends on that other project, and it will then link foo.LIB for you.
Having said that, it sounds like you try to build your two projects with different settings for the C++ version. VS2019 has good support for C++17 and experimental support for C++20, so you can choose. But you need to choose consistently for all your projects.
In larger solutions you can us a .vsprops file for that, which is like an #include for project files. A bit overkill when you have two projects, a lifesaver when you have 150.
It varies a bit how you include 3rd party libraries, sometimes 3rd party libraries have an installation and install themselves like under Common Components sometimes you have to do it manually.
E.g. YourSolution/3rdParty/foo/include
YourSolution/3rdParty/foo/lib
YourSolution/3rdParty/foo/lib/release
YourSolution/3rdParty/foo/lib/debug
Sometimes the libraries have different names then they may be in the same folder.
Once you have that structure go to your project's properties C/C++ and add the include under Additional Include Directories make sure you have configuration "All Configurations" here. Then go to Project properties/Linker/Input and the dependency for Debug Configuration and for the Release Configuration - since usually they are different libraries per configuration. e.g. release/foo.lib and debug/foo.lib (foo.lib foo-d.lib or whatever they are called).
Use the macros to make sure you get the right locations so that they are relative to your solution and project. It is not good having absolute paths. E.g. $(SolutionDir)3rdparty\foo\include
Disclaimer : I am not sure this is the "optimal" way to do it but that is the way I do it.

Compile C++ in VS without requiring MSVCP120D.dll at runtime

I'm trying to make a binary that can be run on any windows machine without the visual c++ stuff installed (I'm assuming that's what MSVCP120D.dll is however my searching was not very fruitful as to what this actually is). I made a game for an assignment and wanted to have other people (non-devs without VS stuff installed), help me test it but they kept getting errors saying that the above dll is missing. I'm not using any Visual C++ stuff and have the /Za flag set to ensure that it's just ANSI C++. Does Visual Studio support compiling ANSI C++ and if so how do I go about making it not use Visual C++ stuff, if it doesn't support this what compiler should I use?
As you can see here, the MSVCP DLL is the platform's implementation of the C++ Standard Library. In short what that means is you cannot distribute your application without needing the "stuff" that these libraries provide. All compilers regardless of platform would need some kind of implementation of the Standard Library. Typically this is distributed in the form of libraries.
However you can distribute your application so that the "stuff" is built in to your program directly, rather than being shipped in a separate DLL. In order to do this, you must statically link your application to the Standard Library.
There are a few ways to accomplish this. One way is in Project Settings. In "Project" > "Configuration Properties" > "C/C++ Code Generation" > "Runtime Library", choose "Multithreaded (/MT)" as opposed to "Mutithreaded (Static)".
By the way, the "D" in "MSVCP120D.dll" you mentioned above means "Debug." This means that you are trying to distribute a debug build of your program. You should (almost) never do this. Distribute release builds instead.
You have three options (in the order I'd recommend):
Don't statically link, instead get people that want to run your game install the visual studio re-distributable package. 32-bit VC 2010 version here: http://www.microsoft.com/en-us/download/details.aspx?id=5555
Statically link the CRT (the dll you don't want to require at runtime) see here for details: How do I make a fully statically linked .exe with Visual Studio Express 2005?
Build an app that doesn't even use the CRT at all. Here you will have to implement your own operator new that calls HeapAlloc(), and operator delete that calls HeapFree(), its an interesting challenge ;). To do this you tell the linker to ignore all default libs.
Build with the static runtime libraries rather than the DLL versions.
Go to Properties, C/C++, Code Generation, Runtime Library and select /MTd or /MT rather than the /MDd and /MD options.
Configure your project to link against the runtime statically rather than dynamically.
First of all the D on the end of the name indicated a debug build. If you make a release build then it will need it without the D. This is important because microsoft do not allow the debug libraries to be distributed without visual studio.
The machine you are trying to run the program on may already have the release runtime installed as lots of programs use it. If not then install http://www.microsoft.com/en-us/download/details.aspx?id=30679 on the machine ( I think that's the right one but can't check at the moment)
You'll want static linking, that 'builds in' the external library calls into your binary. It does have the added affect of larger binary file, but in your case that doesn't sound like that big of a deal.
On a side note, MSVCP120D.dll is the Microsoft Visual C++ 12 debug DLL (dynamic link library) that contains all of debug C++ libaries (i.e. iostream, string, etc). That library is what you would be 'baking in' to your final binary.
Hope that helps.
I encountered this error when I tried to execute my exe on a different machine that had a newer version of Visual Studio on it. You need to change the project properties and re compile in order for this to go away.
To do this:
Open up solution that you are trying to run
Right click on the Project file - > Properties
In Configuration Properties and General, Ensure Platform Toolset is configured to be the correct compiler on your machine. If it is not correct, it should give a message next to it saying that it's not installed.
Build and run the code again and you should no longer get the issue.

Move C++ app with Boost from Linux to Windows with Visual Studio 6

I made a small program with Boost in Linux 2 yrs ago. Now I want to make it work in Windows. I found there are few .a files in my libs folder. I am wondering how to make it works in Windows? do I need to build Boost in Windows to get library or I can download somewhere? I am using Visual Studio 6.
Yes, you'll need to recompile for different platforms. Coincidentally, I posted instructions on this not long ago.
I hugely recommend you do not use Visual Studio 6. It's very dated, and terribly non-conforming. You can get the newer versions for free, as Express. You won't be missing anything.
Many boost libraries are header-only, you don't need to link against anything to use them. Libraries such as boost::filesystem require you to build libs appropriate for your platform and link against them.
Precompiled boost for MSVC7,8,9 can be found here (in the hope that you follow GMan's advice and get rid of VS6 …)
.a files from Unix are like .lib files in Windows. They will not work, and there is no way of "converting" them, short of using a compiler on the original source code.
However, Boost does build on Windows. Just download it (or more likely, the closest version you can find to the one your code was using).
Older versions of Boost did work under VS6, but with a whole lot of stuff disabled (VS6 really just barely qualified as a C++ compiler). If you can, I highly suggest you use a newer version of Visual Studio.
You have a few options. Building Boost will give you the greatest flexibility in working with your application and boost libraries. However, you can download pre-built Boost libraries wrapped up in a nice windows installer here, Boost Packages
But one thing to keep in mind, depending on what you used in Boost, a lot of it is template based so no libraries are required. If you're only using some templatized portions, you don't need to worry about any of this. Just make sure you have boost in your include path when building.
As a side note, you can get free but limited versions of newer MS compilers here: http ://www.microsoft.com/exPress/

Port GNU C++ programs to Visual C++

How do you port C++ programs with makefile made from GNU C++ in Linux to Visual C++?
One thing I can suggest is to use CMake. If you implement your build system with CMake to auto-generate the makefiles for GCC on Linux, it takes only minor modifications to auto-generate projects and solutions for VC++.
Of course, this means learning a whole new build tool, so it may not be for you. It's only a suggestion.
I don't know about an easy way to simply convert from one to another, but..
Assuming you use only ANSI C/C++ features, usually you don't need to convert the makefile, just look which .c/.cpp files are in it and add them to the VS project; you'll also have to check about compiler options and defined macros, to put them inside the VS project. I've done this to compile libs like expat, freetype, agg and others, without problems.
Porting the build system: You could use a Windows port of GNU make, and change the makefile to invoke the Visual C++ command line tools (cl.exe, link.exe, lib.exe, etc.) when building on Windows and the GNU compiler tools when building on Linux. The difficulty of this approach depends on the complexity of the makefiles.
Porting the code: This depends on what APIs and libraries you are using, and what compiler warnings/errors/quirks you will encounter. For a more specific answer, ask a more specific question.
CMake was mentioned. I have used CMake and successfully compiled the resulting Visual Studio project. I found the CMake documentation very unhelpful -- I had to ask an existing user -- and the official manual (which costs money) was out of print at the time. Further, the Visual Studio project it produced was very rigidly formatted according the template preferred by whoever wrote the converter. I was unable to figure out how to customize project options or group source files.
I regularly cross-compile on Visual Studio and G++. For the most part, you just need to add all of the source files and header files into a Visual Studio project ('Add Existing Files', and add your entire source tree) and then compile it. Usually you'll get errors, so you start fixing bugs from there. If you used platform-specific libraries, you may be stuck porting to an alternative or removing features.
One further word of caution: Visual Studio and G++ have different compiler quirks. For the most part, they both conform excellently to the C++ standard, but slightly off-standard code which works in one may not work in the other. I have found this to be particularly true when dealing with templates, with Visual Studio being bizarrely permissive of syntax errors in many cases.
CMake has the nicety of generating visual studio project.
If you do not need that, I suggest Meson build system. Much nicer, similar proposal. Requires python3 and ninja, but noone is perfect. :)

What is the format of a Borland 5.0 project file?

I have an old Borland project which I would like to port to Visual Studio 2008. Is there a way to dump, in a human-readable format, the source file, compile options and dependency information from a .ide file?
I'd like something a bit more comprehensive than the 'Generate Makefile' option.
I think it will be easier just to create a new project in Visual Studio and then add all your source files and libraries into it.
I don't think Visual Studio supports OWL (or any Borland libraries).
If this is a VCL application, options and settings are the least of your concerns, since the VCL API is completely different from MFC.
A lot of the Borland compiler options are actually to provide compatibility with MFC. Other than that there isn't actually much overlap in the compiler options.
I occasionally provide Visual Studio 'solution' versions of my Borland projects to colleagues, and normally is simply a matter of selection the .cpp files in the solution and setting any global defines (these is console mode programs mind you, no GUI).
The greater issue is minor inconsistencies in stream classes,
values.h and deprecated functions that Microsoft has dropped.
That is, _stricmp(), _chdir(), _mkdir() _getcwd() instead of stricmp() chdir() mkdir() getcwd(), etc...
I have generally not found the various Borland generated makefiles very compatible with any other compiler (or even with the Borland compiler for that matter).
I don't know about Borland 5, 6 or latest compilers (latest version I've used is Borland C++ 3.1 back in 1994/95 ...), but if you have the chance to generate a Makefile maybe the best solution is to use that Borland makefile to write a NMAKE compatible makefile by hand, if it's not too large.
Another option is to manually import the header, source files and edit the project (compatibilize source and compilation settings) until the build is successful. I think this can be achieved in a short time.
To what dependencies is your project tied to? VCL? MFC? Just standard libs?