Is there a way to compile a cross platform library to work on all platforms with the single file?
So what I mainly (only?) see is that Windows uses DLL and other platforms each use a different file.
Why are these not standardised? Is there a standard format that can be used instead? If not can this be faked?
Sorry about multiple questions but answering one should invalidate the others.
Libraries contain compiled code, which is actually specific to the architecture of the platform. Since there is no standard agreement between big players on machine architecture, the unfortunate result is that the libraries are not portable across platforms.
The best way is to open source the code and let the users compile the code on the platform they want.
The second best option is to go Java way. Distribute your library in form of jar file containing the class files. And let the users install the right JRE for their platform.
I am not aware of any other options unfortunately.
IDK why object files aren standartized (although you can use GCC for crosscompilation afaik), but the only viable guaranteed crossplatform solution as for right now is source (as far as i know). For example CImg ships as single header file (40kb), but it has some dependencies, it needs backend image processing library/toolchain. Although im not quite sure, maybe there are cross-platform static object formats.
Related
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.
I have compiled my preload file on Ubuntu server (two files for x32 and x64). Where I can get list, in which I will see with what OS my compiled files are compatible and with what I should recompile for compatibility?
Thanks!
Use Linux App Checker developed by ISPRAS and The Linux Foundation. It's designed to perform cross-distro compatibility checks for Linux applications. See sample reports here.
I would start by attempting to execute the program on various Linux distributions in a virtual machine. Pick the top three most popular Linux distributions or the ones your users are most likely to have.
Also, you may be better off to distribute a statically linked binary and offer the source code to others who wish to build it themselves (if you are allowed to distribute source).
I don't know if I fully understand you, but, if my understanding is not that wrong, I'd start by ldd -v. Any OS that is architecture compatible and has the dependent libraries installed in compatible versions should work.
Next, if you plan to support more architectures, you need explicitly to know it and cross compile for every one of it.
So, you must recompile for:
1. Every different architecture.
2. When library versions are not compatible.
This last one is more tricky, since your code may need specific versions to work, but you must know it anyway from start.
Please tell me if it is not what you wanted.
I've got a C++ project where we have loads and loads of dependencies. The project should work on Linux and Windows, so we've ported it to CMake. Most dependencies are now included right into the source tree and build alongside the project, so there are no problems with those.
However, we have one binary which depends on Fortran code etc. and is really complicated to build. For Linux, it's also not available as a package, but only as precompiled binaries or with full source (needs a BLAS library installed and several other dependencies). For windows, the same library is available as binary, building for Windows seems even more complicated.
The question is, how do you handle such dependencies? Just check in the binaries for the supported platforms, and require the user to set up his build environment otherwise (that is, manually point to the binary location), or would you really try to get them compiled along (even if it requires installing like 10 libraries -- BLAS libraries are the biggest pain here), or is there some other recommended way to handle that?
If the binary is independant of the other part of your build process, you definitively should check-in it. But as you cannot include every version of the binary (I mean for every platform and compile flags the user might use) the build from source seems mandatory.
I have done something similar. I have checked-in the source code archives of the libraries/binaries I needed. Then I wrote makefile/scripts to build them according to the targeted platform/flags in a specific location (no standard OS location) and make my main build process to point to the right location. I have done that to be able to handle the correct versions and options of the libraries/binaries I needed. It's quite a hard work to make things works for different platforms but it's worth the time !
Oh, and of course it's easier if you use crossplatform build tools :)
One question to you. Does the users need to modify this binary, or are they just happy it's there so the can use/access it? If they don't need to modify it, check in the binaries.
I would agree, check in the binaries for each platform if they are not going to be modified very often. Not only will this reduce build times, but it will also reduce frustration from unnecessary compilations.
I'm writing a small library in C++ that I need to be able to build on quite a few different platforms, including iPhone, Windows, Linux, Mac and Symbian S60. I've written most of the code so that it is platform-agnostic but there are some portions that must be written on a per-platform basis.
Currently I accomplish this by including a different header depending on the current platform but I'm having trouble fleshing this out because I'm not sure what preprocessor definitions are defined for all platforms. For windows I can generally rely on seeing WIN32 or _WIN32. For Linux I can rely on seeing _UNIX_ but I am less certain about the other platforms or their 64-bit variants. Does anyone have a list of the different definitions found on platforms or will I have to resort to a config file or gcc parameter?
I have this sourceforge pre-compiler page in my bookmarks.
The definitions are going to be purely up to your compiler vendor. If you are using the same compiler (say, gcc) on all your platforms then you will have a little bit easier time of it.
You might also want to try to instead organize your project such that most of the .h files are not platform dependent. Split your implementation (cpp files) into separate files; one for the nonspecific stuff and one for each platform. The platform specific ones can include 'private' headers that only make sense for that platform. You may have to make adapter functions to get something like this to work 100% (when the system libs take slightly differed arguments) but I have found it to be really helpful in the end, and bringing on a new platform is a whole lot easier in the future.
Neither the C nor the C++ standards define such symbols, so you are going to be at the mercy of specific C or C++ implementations. A list of commonly used symbols would be a useful thing to have, but unfortunately I haven't got one.
I don't think there exists a universal list of platform defines judging by the fact that every cross-platform library I have seen has an ad-hoc config.h full of these stuff. But you can consider looking at the ones used by fairly portable libraries like libpng, zlib etc.
Here's the one used by libpng
If you want to look through the default preprocessor symbols for a given system on which you have GCC (e.g. Mac OS X, iOS, Linux), you can get a complete list from the command-line thus:
echo 'main(){}' | cpp -dM
These are often of limited use however, as at the stage of the compilation at which the preprocessor operates, most of the symbols identify the operating system and CPU type of only the system hosting the compiler, rather than the system being targeted (e.g. when cross-compiling for iOS). On Mac OS X and iOS, the right way to determine the compile-time characteristics of the system being targeted is
#include <TargetConditionals.h>
This will pick up TargetConditionals.h from the Platform and SDK currently in use, and then you can determine (e.g.) endianness and some other characteristics from some of the Macros. (Look through TargetConditionals.h to see what kinds of info you can glean.)
When writing an app that one wants to have compile on mac, linux and windows, what is the best way of managing the different libraries that will need to be included on the various operating systems. For example, using the glut opengl toolkit requires different includes on each operating system.
Your question is actually two questions in one:
1) How do I write my C++ code to include the right include files on the right platform?
2) How do I write my Makefile to work on different platforms?
The C++ code question is already answered - find the platform-specific defines and use them to figure out what platform you're on.
Automake or scons are quite complex, and are worth your time only if you intend to release your code to a wide audience. In the case of in-house code, a "generic" makefile with per-platform include is usually sufficient. For Windows, you can get GNU Make for Windows (available from here, or use nmake and limit yourself to the subset of syntax common between all platforms.
If you just need to worry about header files, then the preprocessor will do everything you need. If you want to handle differing source files, and possibly different libraries you'll need a tool to handle it.
Some options include:
The Autotools
Scons
CMake
My personal favorite is CMake. The Autotools uses a multi-stage process that's relatively easy to break, and scons just feels weird to me. Cmake will also generate project files for a variety of IDEs, in addition to makefiles.
There is a good article on Macros. One of the answers how to use conditional compilation based on OS/COmpiler (its near the top).
The use of the Autoconfiguration tools is a nice addition on top of this but is not needed for small projects where it may be easier to detect the OS explicitly, though for larger projects that may need to run on many different types of OS you should also explore the Available autoconfiguration tools mentioned by Branan
Several projects I've worked on use an autoconf-based configure script which builds a Makefile, hence the reason you can build all of them from source with a simple:
./configure
make
make install
Scons has a configuring mechanism that will do a lot of what autotools do without as much complexity, and is pretty darn portable (although not as portable as autotools).
The compiler should have a set of preprocessor symbols it will provide that you can use. For example linux for gcc on a Linux system, _WIN32 for VC++. If you need something more complex then look at autoconf, but that works best for Unix based code.
I'd recommend checking out how some of the larger OpenSource projects handle this. See AutoSense.hpp from (an old release of) Apache Xerces.
If the libraries offer the same API on the different platforms, I would create a "proxy" include file containing all the necessary #ifdefs. That 'platform-independent' include file is then included in your client code instead of cluttering it with numerous and ugly-reading preprocessor commands. These will be contained in the ugly and cluttered platform-independent include.
If the API differs across platforms, you will need to create your own abstraction.
Perhaps this is a cop-out answer, but have you looked at how boost handles this? They build on quite a few platforms without autoconf, although they do have their own build system - bjam - that probably handles some of the same situations. They also do a nice auto-linking trick on windows that automatically selects the right version of libraries for linking depending on the version of the MSVC compiler. Based on your initial description, it sounds like just macro defs checking for various platforms/compilers might do the trick, but perhaps there is more to your problem that would prevent this.