Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I'm getting a lot of conflicting information on how to build native Windows apps using GCC.
Basically, I want to learn Windows programming, from a familiar standpoint. I want to learn the nitty gritty of which libraries need to be included with which headers, etc etc. So I can get some idea of the underlying implementation. I feel that visual studio takes a lot of this away with what seems to be a sometimes opaque build process (it frustrates me that when I include the header the libraries are automatically linked, making it hard for me to see what is doing what)
EDIT: Thanks to Ben and Serge for pointing out the falsity of the last statement. VS does not automatically include libraries based on what headers are included, rather it links a number of default libraries, regardless of what headers are included, however only functions/classes etc. required by the translation units will end up in the final executable.
Is there a way that I can develop for Windows, using the Windows API (i.e. not libc) but using a less "user-friendly" environment?
I would preferably like to stick with GCC (MinGW etc.), but I am open to other tool chains. I just want to get under a bit of that bloat and abstraction that visual studio has.
Can I just download the windows SDK and start building using MinGW? If not, where can I get the headers and libraries I need for native development? Will it compile correctly using something like minGW?
A lot of questions!
Thanks!
SUMMARY: See Serge's very helpful answer!
Thanks to everyone for the info!
If you want to do command line builds, nothing prevents you from writing your own NMake file that describes what files get compiled with what flags and how they are all linked into their own executable.
The windows compiler is cl.exe.
The windows linker is link.exe
Visual Studio, (or its free variant Visual Studio Express) do not automatically find the library associated to a header. Simply by default, it uses a set of standard libraries. But I can tell you that as soon as you will use less standard API, you will have to declare both headers and libraries. And if you look a little deeper in the project properties, you will find the exact command line for compilation and linking phases.
You can use either MSVC tools or MingW ones, but never try to mix them ! The object formats are not compatible with each other
EDIT :
I will now describe how it works in the version I know (MSVC Express 2008). The configuration of the project is available under Project / Properties. You normaly find 2 configuration here (Debug and Release) but can always add new special build configurations via Configuration Manager. You choose the config you want to tweek (or choose All configurations to apply changes everywhere.
Under Configuration properties you find (among others) items for C/C++ (compilation phase) and Linker (link phase) with menus to tweak almost everything. Last menu is always Command line and gives the actual command line that will be used.
If you use another version, your mileage may vary, but I had always been able to find the configuration under Project / Properties on older MSVC versions ...
EDIT 2 :
Concerning the list of default libraries, they are used by the linker independantly of headers you could have used or not in your different sources. But as they are libraries and not object modules, only object modules (contained in libraries) that are actually required by the program directly or indirectly will end in the executable. I almost never used the Ignore default libraries option. Mainly when I wanted to be sure that I did not use a system library to reduce the size of the executable for a very special use case.
Related
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.
I use Visual Studio 2017 (but applies to any version from 2010+) and I've been trying to come up with a way to organize my Debug/Release libraries in such a way as to avoid all these linking errors we get, when mixing different versions of the Runtime libraries. My goal seems simple, conceptually, but I have not yet figured out a way to achieve all I want.
Here's what I have, and what I'd like to do:
Common Libraries:
ComLib1
ComLib2
...
Exe1:
ComLib1
ComLib2
...
Exe1Lib1
Exe1Lib2
...
Exe1
Exe2:
ComLib1
ComLib2
...
Exe2Lib1
Exe2Lib2
...
Exe2
So 2 different executable, using a set of common libraries and Exe-specific libraries.
I want to create 4 different build configurations.
Cfg1:
This would contain debugging info/non-optimized code for all libraries, including the Common Libraries.
Cfg2:
This would contain debugging info/non-optimized code for all Exe-specific libraries, but NOT for the Common Libraries.
Cfg3:
This would contain a combination of debugging info/non-optimized code libraries for some libraries, and non-debugging info/optimized libraries for the remaining ones.
Cfg4:
You guessed it. This would contain non-debugging info and optimized code for all.
My first attempt was to basically create 2 sets of binaries for each library; one compiled in Debug Mode (with /MTd /Od) and another one compiled in Release Mode with (/MT /O2). Then pick one or the other version in my various configurations. This was fine for Cfg1 & Cfg4 (since all Runtime libraries are consistent throughout), but ran into those those linking errors for Cfg2 & Cfg3.
I understand why I get these errors. I'm just not sure how one goes about resolving these things, in what I would think would be a common scenario. Maybe Cfg3 is uncommon, but I would think Cfg1,2 & 4 are.
Thanks for your inputs.
EDIT
I didn't really think I needed to add this information because I wanted to keep my question short(er). But if it can help clarify my goal, I'll add this up.
This is for a Realtime simulator. I just can't run every single library in a typical Debug configuration, as I would not be able to maintain Realtime. I seldom need to Debug the Common Libraries because they're mostly related to Server/IO tasks. The Exe libs mostly contain math/thermodynamics and is where I mostly spend my time. However, 1 Exe lib contains reactor neutronics, which involved heavy calculations. We typically treat that one as a black-box (cryptic vendor-provided code) and I almost always want to run it using Optimized code (typical Release settings).
You can not use different runtime libraries in the same process without some special considerations (e.g. using a DLL or so with no CRT object in the interface to make them entirely seperate) without either link errors or risking runtime issues if CRT objects are passed between.
You can mix most of the general optimisation options within a module with the notable exception with link time code generation that must be the same for all objects. The release runtime libraries are also generally usable for debugging as long as your own code is not optimised.
To easily switch you will want a solution configuration for each case you want (so 4). You can make one project configuration be used by multiple solution configurations if you do not want some that are duplicates but it must follow the previously mentioned limitations, and can confuse things like output directory. You can also use property sheets to share settings between multiple projects and configurations.
I've done similar using predefined macros for either the output directory path or the target filename.
For example, I use $(Platform)_$(Configuration) which expands to Win32_Debug or Win32_Release.
You can use environment variables as well. I haven't tried using preprocessor macros yet.
Search the internet for "MSDN Visual Studio predefined macros $(Platform)".
So this is how I ended up getting what I wanted.
Assuming I'm using the static Runtime libraries, I think I'll keep the typical Debug/Release (/MTd and /MT, respectively) libraries for my Common Libraries and create 3 sets of libraries for my Exe's:
Exe1Lib1Release: Typical Release Configuration
Exe1Lib1Debug: Typical Debug Configuration
Exe1Lib1DebugMT: Non-optimized code with debugging info, but using the MT Runtime libraries
Cfg1:
Will use the typical Debug libraries all around
Cfg2 & Cfg3:
Will use the typical Release libraries for the Common Libraries, and the Exe1Lib1DebugMT for the Exe's libraries
Cfg4:
Will use the typical Release libraries all around.
EDIT
Actually, Cfg2 & Cfg3 settings are more accurately represented by:
Cfg2:
Will use the typical Release libraries for the Common Libraries, and the Exe1Lib1DebugMT for the Exe's libraries
Cfg3:
Will use the typical Release libraries for the Common Libraries, and a combination of Release and Exe1Lib1DebugMT for the Exe's libraries
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
(I've just edited the question to be more specific)
I know that this question might be too general to answer, but I'm just can not find good tutorial on this, so trying to seek for help here.
I'm new to C++, previously my main programing language is Java and Python. The way that C++ manage third-party lib is somehow confusing for me......While Python can easily install things with pip, Java can import the JAR, how C++ organize those things?
I would like to split my question into few parts:
Here is some understanding and question of mine:
As long as the compiler, or IDE, know the path of the lib, then everything is fine. So when saying install, we just add the path of the lib to some system path. And for IDE, we just config the setting so that it can resolve the lib in given path. Correct me if anything is wrong.
Some C++ lib are all source code, and some contains sth. like .so or .dll, what is that? And what's the difference? I saw some lib saying that it can be used with simply include a few headers, but some require static linking, what does it mean?
What's is a general good approach to manage all those lib? (For example, in python, pip will simply install to some global scope, or we use vitrual env to manage that. Then anything similar to pip in C++?
More specifically, I'm using CLion, and Clion use CMake, so maybe all I suppose to do is config the CMakeList.text correctly and then the IDE will resolve all lib and compile correctly?
Again sorry for such general and somehow opaque question, but I'm totally lost as a newb for C++, which is much more complicated than Python and Java I used before.....
Any good tutorials might be of great help, thanks!
C++ doesn't. C++ is a language not a specific compiler or implementation.
With that said, for most compilers, building a C++ application is done in multiple steps:
Edit
Compile to object file
Link to executable.
The C++ compiler is technically only involved in step 2 (and really only part of step 2).
Most compilers and linkers since long ago allow you to put header- and library-file anywhere, and then there are flags passed to the compiler and linker on the command-line that tell the compiler and linker where to find the files.
For header files the (common) command-line option -I (upper-case i) is used to add a path to be searched for header files. For libraries the option -L similarly adds a path to be searched by the linker for libraries. There are of course default paths built into the compiler and linker, and the -I and -L options adds to those defaults.
Then to link with an actual library, the linker-option -l (lower-case L) is the common option to use. Each -l options list a single library that needs to be linked into the executable.
In regards to CMake and CLion, the CLion IDE doesn't really link anything at all. Instead it uses CMake to create a set of makefiles which contains the information used to build the targets.
Lastly there are some C and C++ alternatives to PIP or other languages package managers, but generally you use the standard way to install programs and libraries on your system.
Like on Windows you find an installer, and then modify your project settings (using CMake CMakeLists.txt, raw Makefile, or IDE settings) to add the directories needed.
For Linux systems you use the standard package manager (like apt on Debian-based systems, or yum on Fedora-based systems, etc.) to find and install libraries. Then the libraries and their header files will be installed in the default locations. You still need to set up the build-environment to actually link to the libraries.
The common way is, that you include the thirdparty stuff as a .dll or you can include it direct as code (as example boost ... you have to load it and to make it work you only have to include the parts you want, and for some parts from boost you have to build it with your compiler settings and include the .dlls)
The thing with the manager like you want I only now from VisualStudio with NuGet. I have no idea if is there such a thing for CLion.
As example you can look to the example from opencv:
https://docs.opencv.org/master/d3/d52/tutorial_windows_install.html
For your questions:
Correct. But in case the lib have to match also the settings (32/64 bit, release/debug)
If you only have to include some headers, then the code is direct included to your project and compiled with your code. If you have to link it as a binary (.dll windows, .so Unix (i think please correct me if wrong)) than the code is compiled and you link the compiled functions to your code.
Here a answer to .so:
What are .a and .so files?
And here for static and dynamic libs:
When to use dynamic vs. static libraries
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I used to program in Windows with Microsoft Visual C++ and I need to make some of my portable programs (written in portable C++) to be cross-platform, or at least I can release a working version of my program for both Linux and Windows.
I am total newcomer in Linux application development (and rarely use the OS itself).
So, today, I installed Ubuntu 10.04 LTS (through Wubi) and equipped Code::Blocks with the g++ compiler as my main weapon. Then I compiled my very first Hello World linux program, and I confused about the output program.
I can run my program through the "Build and Run" menu option in Code::Blocks, but when I tried to launch the compiled application externally through a File Browser (in /media/MyNTFSPartition/MyProject/bin/Release; yes, I saved it in my NTFS partition), the program didn't show up.
Why? I ran out of idea.
I need to change my Windows and Microsoft Visual Studio mindset to Linux and Code::Blocks mindset.
So I came up with these questions:
How can I execute my compiled linux programs externally (outside IDE)?
In Windows, I simply run the generated executable (.exe) file
How can I distribute my linux application?
In Windows, I simply distribute the executable files with the corresponding DLL files (if any)
What is the equivalent of LIBs (static library) and DLLs (dynamic library) in linux and how to use them?
In Windows/Visual Studio, I simply add the required libraries to the Additional Dependencies in the Project Settings, and my program will automatically link with the required static library(-ies)/DLLs.
Is it possible to use the "binary form" of a C++ library (if provided) so that I wouldn't need to recompile the entire library source code?
In Windows, yes. Sometimes precompiled *.lib files are provided.
If I want to create a wxWidgets application in Linux, which package should I pick for Ubuntu? wxGTK or wxX11? Can I run wxGTK program under X11?
In Windows, I use wxMSW, Of course.
If question no. 4 is answered possible, are precompiled wxX11/wxGTK library exists out there? Haven't tried deep google search.
In Windows, there is a project called "wxPack" (http://wxpack.sourceforge.net/) that saves a lot of my time.
Sorry for asking many questions, but I am really confused on these linux development fundamentals.
Any kind of help would be appreciated =)
Thanks.
How can I execute my compiled linux
programs externally (outside IDE)? In
Windows, I simply run the generated
executable (.exe) file
On Linux you do the same. The only difference is that on Linux the current directory is by default not in PATH, so typically you do:
./myapp
If you add current dir to the path
PATH=".:$PATH"
then windows-like way
myapp
will do, but this is not recommended due to security risks, at least in shared environments (you don't want to run /tmp/ls left by somebody).
How can I distribute my linux application?
In Windows, I simply distribute the executable files with the corresponding DLL files (if any)
If you are serious about distributing, you should probably learn about .deb (Ubuntu, Debian) and .rpm (RedHat, CentOS, SUSE). Those are "packages" which make it easy for the user to install the application using distribution-specific way.
There are also a few installer projects which work similarly to windows installer generators, but I recommend studying the former path first.
What is the equivalent of LIBs (static library) and DLLs (dynamic library) in linux and how to use them?
.a (static) and .so (dynamic). You use them in more or less the same way as on Windows, of course using gcc-specific compilation options. I don't use Code::Blocks so I don't know how their dialogs look like, in the end it is about adding -llibrary to the linking options (guess what: on windows it is about adding /llibrary ;-))
Is it possible to use the "binary form" of a C++ library (if provided) so that I wouldn't need to recompile the entire library source code?
Yes. And plenty of libraries are already present in distributions.
Note also that if you use .deb's and .rpm's for distribution, you can say "my app needs such and such libraries installed" and they will be installed from the distribution archives. And this is recommended way, in general you should NOT distribute your copy of the libraries.
If I want to create a wxWidgets application in Linux, which package should I pick for Ubuntu? wxGTK or wxX11? Can I run wxGTK program under X11?
Try wxGTK first, dialogs may look better, gnome themes should be used etc.
If question no. 4 is answered possible, are precompiled wxX11/wxGTK library exists out there? Haven't tried deep google search.
Try
apt-cache search wx
(or spawn your Ubuntu Software Center and search for wx)
In short: you will find everything you need in distribution archives.
Navigate to the folder with your compiled program and execute ./program
Send the program, plus any .so files
.a is static library, .so is shared libraries.
Yes, but often you need to compile it yourself first.
Not sure about wxWidgets distributions, though.
Since Ubuntu comes with wxGTK packages you should definitely build against them. For development you should use a debug version though, so it might be good to build yourself, but for deployment building against the packages the system provides seems better.
wxX11 is a worse choice than wxGTK, use it only for systems where wxGTK doesn't exist or requires newer GTK libraries than are available.
Why not just stick with what you know and develop in .NET? Ubuntu comes native with Mono. You could keep using Visual C++ or step up to C# and make your life a whole lot easier.
A piece of general advice to Linux newcomers, but who are technically minded to begin with, is: You should learn to use your chosen distribution properly.
In your case, that means learning how to acquire the right development packages provided by Ubuntu. For instance, some other people are advising you to download the source for libraries you are going to use, but the better way is to use Ubuntu's package system to download the libraries you want to program against, together with the headers for that library (often put in a separate package) as well as the debug symbols for the library (also often in a separate package).
Look in the System->Administration menu in Ubuntu for the Synaptic tool, which allows you to search the package repositories on the Internet. You'll almost certainly find packages for the libraries you need, as well as all tools.
1, Unix generally doesn't have a particular extension for an executable - so myprog.exe would just be myprog.
You might have to set it to be executable if the IDE doesn't do this automatically, type "chmod +x myprog"
5, For wxWindows I would download the source and build it, check the build instructions but it's probably just a matter of "configure;make;make install". Generally in Unix you build libs form source so that they can correctly find all the components on your machine - you also have the source of examples etc.
I just added some information to rlbond's answer.
It is depens on Linux version. If you use a Ubuntu - create a deb-package. (http://ubuntuforums.org/showthread.php?t=51003)
Can I run wxGTK program under X11?
Yes, if you have wxGTK package installed :)
This is not really going to answer your questions, but I think is a valid recommendation.
You have two issues you are trying to deal with:
The Linux environment.
Making sure your program is
portable.
If I were you I would load CodeBlocks on Windows and run against either Cygwin or Mingw, that will help you make sure your code is portable across platforms. You are familiar with the environment and would gain maximum productivity getting over the OS hurdle.
Once you are satisfied with the above then take your code and move it to Linux. At that point any porting effort should be trivial.
When you say your program didn't show up I assume you mean that it was there in the file browser but when you double clicked it you got a busy cursor for a moment and then nothing happened?
If so then it means that the program failed to run, probably because it couldn't find the dynamic libraries it's linked against. To diagnose the problem you can run it from a terminal and then you'll be told what the problem is.
You might want to read the manual page for ld.so i.e. type
man ld.so
into a terminal. This tells you where the Linux dynamic library linker looks for libraries at run-time. It also refers you to another useful tool called ldd which I recommend becoming familiar with if your are doing Linux development.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Imagine you're free to choose a tool like GNU make for a new C++ project. What would you choose? Are any usable substitutes out there?
It shall have/be
a command line interface
"easy" to understand
easy to set up for a default c++ project
may support src/bin seperation as common for Java
may not add too much dependencies to other software/libs
platform independent (new)
features:
build rules / templates like make but in an human readable way
recursively crawling directories and applying the rules if there is no other
"Makefile"
configuration by exception
Note:
Nothing's wrong with GNU make. I just don't like its grammar, all the stuff that grows in the years and the silly recursive make problems. I'm using gmake for years now.
I use cmake, and I'm very glad I made the switch.
EDIT
Feature list as found in the wikipedia article:
Configuration files are CMake scripts, which use a programming
language specialized to software builds
Automatic dependency analysis built-in for C, C++, Fortran and Java
Support of SWIG, Qt, via the CMake scripting language
Built-in support for many versions of Microsoft Visual Studio including versions 6, 7, 7.1, 8.0, and 9.0
Generates build files for Eclipse CDT (C/C++ Development Tools)
Detection of file content changes using traditional timestamps,
Support for parallel builds
Cross-compilation
Global view of all dependencies, using CMake to output a graphviz diagram
Support for cross-platform builds, and known to work on
Linux and other POSIX systems (including AIX, *BSD systems, HP-UX, IRIX/SGI, and Solaris)
Mac OS X
Windows 95/98/NT/2000/XP, Windows Vista and MinGW/MSYS
Integrated with DART (software), CDash, CTest and CPack, a collection of tools for software testing and release
But to be honest: Just about anything is better than the gnu toolchain.
SCons and waf are good (well, IMHO anyway) build systems, and depend only on Python.
How about "gnu make"?
You asked for something like it without giving any indication of what features you want that aren't supported by gnu make.
Boost.Jam
It has the features you named
command line interface;
easy;
it comes from the C++ library collection Boost, so it has good support for C++ (and it's not limited to C++, either);
it stores executables in places under the bin directory, depending on what build request you've commanded. If you use gcc 4.3.2, than you get the executables under
bin/gcc-4.3.2/debug -- when executing bjam
bin/gcc-4.3.2/release -- when executing bjam release
bin/gcc-4.3.2/release/inlining-off/threading-multi -- when executing bjam release inlining=off threading=multi
bin/gcc-4.3.2/release/threading-multi -- for bjam release inlining=full threading=multi because inlining=full is default for release.
it doesn't need the full Boost library collection, only Boost.Build and Boost.Jam are necessary;
platform independent;
the Jamfile syntax is easy, but powerful;
you can divide the build config into many Jamfiles in subdirectories.
CMake should answer most, if not all for your requirements.
It will generate the Makefiles for you.
It has a good domain specific primitives, plus a simple language for the times you need to do something special.
It solves most of the problems with recursive make (see recursive make is considered harmful paper).
It uses an out-of-source build, so you have your bin / src separation.
I found it easy to write, easy to maintain, and fast to build.
... Plus:
It is cross platform.
With CText and CDash it has what you need for setup a continues integration service.
See also this answer to Recursive Make - friend or foe?
SCons + swtoolkit
G'day,
I'd agree with the couple of answers, so far, that recommend sticking with gmake.
Maybe have another look after reading the first few chapters of Robert Mecklenburg's excellent book "Managing Projects with GNU Make" (sanitised Amazon link).
Or, even better, is to search out a copy of the previous edition called "Managing Projects With make" by Andrew Oram and Steve Talbott. The first few chapters give an excellent description of (g)make and [Mm]akefile basics.
And I see you can buy a second hand copy of the 2nd ed. from Amazon for the princely sum of $0.01! (sanitised Amazon link)
After reading that intro you'll even understand how make is backward chaining, which is a bit non-intuitive when just looking at make's behaviour.
HTH
cheers,
Autotools -- autoconf/automake/libtool they are very poweful build instruments.
Its take some time to start with them, but after -- they serv you very well.
And what is more important they are significantly more powerfull then their replacements (CMake, BJam, SCons etc).
How are they more powerfull?
Transparrent support of building both static and shared libraries via libtool.
Support of uninstall (no in CMake)
Support of standard installation paths -- very important in packaging.
Full support and integration of gettext.
Transparent and strightforward support of cross compilation.
Many things. CMake may do most of things but for each one of them you should write long scripts or specify many things manually.
What's wrong with gmake?
What issues does it have that mean you want to use it. There's no point in recommending another tool if it has the same perceived issues as gmake.
we're using gmake in our build system and we're extremely happy with it's performance, flexibility and features