C/C++ cross-platform compilation - c++

How do I make my program cross-platform? I understand that each operating system has their own API calls and you would use #ifdef, but I don't understand how you can make it compilable on each platform. For instance Linux uses Makefile but I don't think Windows or Mac does. I was recommended qmake and cmake, but it doesn't seem to be widely used in github projects. I usually see them having ./configure and a Makefile instead. Two projects that pique my curiosity on how they're cross-platform are VLC and ffmpeg.

Related

Compiling .cpp file using Cmake Software

I want to create a binary file after compiling .cpp file and create a plug-in for a speech processing software (Praat).
However, this binary file creates compatibility issues on different platforms (Windows, Mac , Linux). I want to solve this by compiling the code using CMake.
Am I correct? I'm new to CMake. Could anyone provide any insight?
No, Cmake just help you in building process, clearly it makes Makefile's for you. you cannot compile a cpp file to a single (or plugable) binary file and expect that it could work on different platforms.
Also you could write your programs with Cross-Platform in mind, but they need to be compiled for each platform.
You could use platforms like Qt or Boost which help you write more Cross-Platform codes and compile them under different platforms without worrying about differences.
Also, The Qt has its own build system named QMake which is very easy to use and your use qmake instead of cmake to make a cross platform build system.
Also if you need truly cross platform binary programs, you could try things like Java.

Better way to give provide path of libraries while compiling in C++

I pretty new to C++. I was wondering, as what is considered generally a neat way to provide paths for various files/libraries while compiling or executing c++ codes.
For ex:
I have Boost libraries installed in some location on my system. Lets call it X
In order to execute anything I have to type in
c++ -I LongpathWhichisX/to/boost_1_60_0 example.cpp -o example
Similarly, also Long path for the input file while executing the code.
Is there a better way to address it. Is it possible to create environment variables lets Y, which refers to path 'X'. And we can use following command to compile code
c++ -I Y/to/boost_1_60_0 example.cpp -o example
Best way is to use build tools. For example you can use Make. You define all your include paths (and other options) in the Makefile. In console you just have to call make to build your project or something like make run to run your project.
The usual way is to make a Makefile where you can specify all needed paths and compile options in proper variables.
If you don't want/need a Makefile and rather want to run compiler from command-line, then you may use the CPATH environment variable to specify a colon-separated list of paths to include files.
This is a broad question but the other answers highlight the most important step. It is essential to learn build tools like make because they will make it easier to build your projects during development and for others to build it later. In the modern programming age though this is not enough. If you are using something like Boost (which targets many platforms) you will probably want to make your build cross-platform as well. For this you would use either cmake or autotools which both have scripts that make it much easier to locate the Boost libraries (and others).
Any other build systems, in my opinion, are a pain and are the bane of maintainers of Linux distributions. CMake used to be in that catergory but it has gained wide acceptance now. CMake targets building cross-platform projects across operating systems (Windows and Unixes) better (again in my opinion) because it attempts to provide the native build system on each platform (for example: Visual Studio in Windows, Make on all Unices, XCode on Mac). The autotools instead target the Unix environment with much greater depth (you have a bit of a harder time on Windows, but you can target embedded Unix systems to high end Unix server systems with much more flexibility).
Note: Autotools support for cross-compiling is superior in almost every way to other solutions. I always cringe when I download something that needs to be cross compiled for Arm Linux and it uses some weird build system. Funnily enough, boost is one of these.
This is a bit of a long winded answer. In summary, it is essential that you learn a build system for native development. It is part of your skill set and until you have that skill you can't really contribute to open-source projects or even your employer developing closed-source projects.

Releasing a program

So I made a c++ console game. Now I'd like to "release" the game. I want to only give the .exe file and not the code. How do i go about this. I'd like to make sure it will run on all windows devices.
I used the following headers-
iostream
windows.h
MMSystem.h
conio.h
fstream
ctime
string
string.h
*I used namespace std
*i used code::blocks 13.12 with mingw
& I used the following library-
libwinmm.a
Thank you in advance
EDIT
There are many different ways of installing applications. You could go with an installer like Inno or just go with a regular ZIP file. Some programs can even be standalone by packaging all resources within the executable, but this is not an easy option to my knowledge for C++.
I suppose the most basic way is to create different builds for different architectures with static libraries and then find any other DLLs specific to that architecture and bundle it together in one folder. Supporting x86/x86-64/ARM should be enough for most purposes. I do know that LLVM/Clang and GCC should have extensive support for many architectures, and if need be, you should be able to download the source code of the libraries you use and then compile them for each architecture you plan to support as well as the compilation options you need to compile to each one.
A virtual machine can also be helpful for this cross-compilation and compatibility testing.
tldr; Get all the libraries you need in either static or dynamic (DLL) format. Check that they are of the right architecture (x86 programs/code will not run on MIPS and vice versa). Get all your resources. Get a virtual machine, and then test your program on it. Keep testing until all the dependency problems go away.
Note: when I did this, I actually had some compatibility issues with, of all things, MinGW-w64. Just a note; you may need some DLLs from MinGW, or, if you're using Cygwin, of course you need the Cygwin DLL. I don't know much about MSVC, but I would assume that even they have DLLs needed on some level if you decide to support an outdated Windows OS.

A single makeFile-Windows/Linux/Mac OS

We have some applications written in C/C++ and makefiles for the same. Currently, we are using the GNU make system on windows (cygwin based). The makefiles were written long back considering only Windows OS in mind. Now we are going to revamp everything.
I am unaware of the factors to be considered while writing the makefiles so as to make them cross platform compatible. I looked at some Sources on the Internet, but they were unsatisfactory. Can someone please list out the issues to be considered while writing the makefiles so as to make them compatible across various platforms.
PS: I have seen this link, but i think it isn't what i want.
Makefiles and cross platform development
You can use cmake - it's a cross platform tool which generates makefiles or projects files with respect to your platform. So instead of writing Makefile you write CMakeLists.txt, then you run cmake and it will generate Makefiles. When you want to compile your program on another platform you just ru-run cmake with different target project system.

Compiling linux library for mingw

I have been using a socket library for C++. Some other info: 32 bit Linux, Codelite and GCC toolset. I want to be able to compile my program for Windows using the windows edition of Codelite. The socket library I have been using doesn’t have a mingw32 build of the library, but it’s open source. So how can I make a mingw32 build of the socket library so I can make a windows build using the source provided?
Most open source linux libraries are built with the make build system (although there others like jam etc, and custom written scripts for building). MinGW comes with the make utility, it's mingw32-make.exe. It may be possible (if you're lucky) to simply rebuild your library by making it on Windows.
The more usual scenario is that you will need to configure the project before you can build it though. The windows shell doesn't support the scripting requirements required to configure, but there's another part of the MinGW project that does called MSYS. If you install msys and all the required tools you need for it, you'll be able to ./configure your project before running make.
Of course, the above will only work if the library is written to be portable. There are some breaking difference between the linux socket implementation (sys/socket.h), and the windows implementation (winsock2.h). You may be forced to edit chunks of the code to ensure that it is versioned correctly for the platform (or that any dependencies required are also built for Windows).
Also, there is the chance that the library may already be built for Windows, but using a different compiler like MSVC, which produces .lib and .dll files. Mingw requires .a files for libraries, but a clever feature is the ability to link directly against a .dll, without the need for an imports library, so you can often use an existing windows library that was not built against Mingw (Although this won't help for static linking). There is also a tool, dlltool, which can convert .lib to .a.
If you give detail on the specific library you're working with, I may be able to pick out for you what needs to be done to run it on Win.
You port it to the new platform. :)
You're fortunate that it is opensource, because then it would be practically impossible to port it (You'd have to pay $$$'s to get a copy of the code for a particular license, or rewrite the entire product).
Enjoy.
Alternatively, they may well already have a port... Check the documentation for the library you are using.
First off your going to need to make sure that you aren't including any Linux specific libraries.