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.
Related
I'm new to Windows programming and found that lots of prebuilt libraries for Windows offer libraries like lib-mingw, lib-vc2019, lib-vc2017...
Could anyone help to point out
what is the difference? Which library should I use in what case?
If I want to use Clang on Windows, which one should I use?
Why these different libraries rarely seen on Linux (let's say
Ubuntu), does package managers like apt hide this detail? In other word, why there's no such thing like lib-gcc.a, lib-clang.a on Linux platform?
Mingw (GCC), VC2019 and VC2017 are different compilers. Use the library corresponding to your compiler.
I'm not sure but I think none of them will work with Clang. At least on Linux GCC and Clang are very similar. I mean they are mostly binary compatible, many same compiler flags, many same compiler extensions. Clang tried to make it possible to easily replace GCC in your build pipeline. But all these information is for Linux.
These libraries are not seen on Linux because all these compilers are Windows compilers
You can always build a library with your compiler to use it in your project with your compiler (if you have the sources).
If it's a third party closed source library and you are a paying customer you can ask if they build it for you. It's usually better the add a new compiler to the build pipeline than to lose a customer.
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.
Is it possible to compile a C/C++ source code that executes in all Linux distributions without recompilation?
If the answer is yes, can I use any external (non-standard C/C++) libraries?
I want distribute my binary application instead of distribute of source code.
No, you can't compile an executable the executes in all Linux distributions. However, you can compile an executable that works on most distributions that people will tend to care about.
Compile 32-bit. Compile for the minimum CPU level you're willing to support.
Build your own version of glibc. Use the --enable-kernel option to set the minimum kernel version you're willing to support.
Compile all other libraries you plan to use yourself. Use the headers from your glibc build and your chosen CPU/compiler flags.
Link statically.
For anything you couldn't link to statically (for example, if you need access to the system's default name resolution or you need PAM), you have to design your own helper process and API. Release the source to the helper process and let them (or your installer) compile it.
Test thoroughly on all the platforms you need to support.
You may need to tweak some libraries if they call functions that cannot work with this mechanism. That includes dlopen, gethostbyname, iconv_open, and so on. (These kinds of functions fundamentally rely on dynamic linking. See step 5 above. You will get a warning when you link for these.)
Also, time zones tend to break if you're not careful because your code may not understand the system's zone format or zone file locations. (You will get no warning for these. It just won't work.)
Most people who do this are building with the minimum supported CPU being a Pentium 4 and the minimum supported kernel version being 2.6.0.
There are two differences which are among installations. Architecture and libraries.
Having one binary for different architectures is not directly possible; there was an attempt to have binary for multiple archs in one file (fatelf), but it is not widely used and unlikely to gain momentum. So at least you have to distribute separate binaries for ia32, amd64, arm, ... (most if not all amd64 distros have kernel compiled with support for running ia32 code, though)
Distributions contain different versions of libraries. You're fine as long as the API does not change, you can link to that library. Some libs ensure inary backwards-compatibility within major number (so GTK2.2 app will run fine with GTK2.30 lib, but not necessarily vice versa). If you want to be sure, you have to link statically with all libs that you use, except the most basic ones (probably only libc6, which is binary-compatible accross distros AFAIK). This can increase size of the binary, and it one of reasons why e.g. Acrobat Reader is relatively big download, although the app itself is not specially rich functionality-wise.
There was a transitional period for c++ ABI, which changed between gcc 2.9 and 3 (IIRC), but the old ABI would be really just on ancient installations. This should no longer be an isse for you, and if you link statically, it is irrelevant anyway.
Generally no.
There are several bariers.
Different architectures
While a 32bit binary will run on a x86_64 system, it won't work vice versa. Plus there is a lot of ARM systems.
Kernel ABI
Kernel ABI changes very slowly, but it does change, therefore you can't really support all possible versions. Note that in some places kernel 2.2 is still in use.
What you can do is to create a statically linked binary. Such binary will include all libraries your app depends on, and it will work on all systems with the same architecture and a reasonably similar kernel version.
I have a program that I am sharing with a third party. I will be providing a bin executable to them. It is written in c++ but uses some c as well. they are suggesting that it needs to be c only. Do you guys think this will be a problem since I will be compiling and building it on a sparc station that will somewhat match their system specs like solaris 9 and the chipset (32 or 64) depending on what they use?
is solaris 9 able to compile the c++ code that i used or do they need to add c++ runtime libraries on their end. I am using c++ std classes. in any event if i am building it all on my end why worry about what they have? its not a static/dynamic lib that i am sharing where i think that would come into play.
just curious since they are saying it needs to be a c compilation. I suspect if they are expecting a lib then perhaps I need to address that but if its just a executable then the system specs like os and chipset is all that matters?
if i am wrong in this assumption please let know where.
Worst case you can always statically link in the C++ runtime library.
If you are only sending them an executable, I don't see why the language makes any difference whatsoever. If you're also sharing code, of course, that's an entirely different story.
Since you're providing them with only an executable (no shared libraries), you shouldn't have too much trouble.
Just run a ldd command on your binary and see which C++ libraries it links against (you might see libstdc++ for instance, if you use g++); you should include those along with your executable. Don't rely on the user having them, they might be missing or might be incompatible. You will want to use the -rpath (linker switch) to make sure your binary will use the libraries you provide and not any library found in the system.
Also, it's better to compile on an older Solaris to provide compatibility, i.e. don't compile on Solaris 10 for Solaris 7, but on 7 for 10. You get the ideea...
Is it possible to use shared object files in a portable way like DLLs in Windows??
I'm wondering if there is a way I could provide a compiled library, ready to use, for Linux. As the same way you can compile a DLL in Windows and it can be used on any other Windows (ok, not ANY other, but on most of them it can).
Is that possible in Linux?
EDIT:
I've just woke up and read the answers. There are some very good ones.
I'm not trying to hide the source code. I just want to provide an already-compiled-and-ready-to-use library, so users with no experience on compilation dont need to do it themselves.
Hence the idea is to provide a .so file that works on as many different Linuxes as possible.
The library is written in C++, using STL and Boost libraries.
I highly highly recommend using the LSB app / library checker. Its going to tell you quickly if you:
Are using extensions that aren't available on some distros
Introduce bash-isms in your install scripts
Use syscalls that aren't available in all recent kernels
Depend on non-standard libraries (it will tell you what distros lack them)
And lots, upon lots of other very good checks
You can get more information here as well as download the tool. Its easy to run .. just untar it, run a perl script and point your browser at localhost .. the rest is browser driven.
Using the tool, you can easily get your library / app LSB certified (for both versions) and make the distro packager's job much easier.
Beyond that, just use something like libtool (or similar) to make sure your library is installed correctly, provide a static object for people who don't want to link against the DSO (it will take time for your library to appear in most distributions, so writing a portable program, I can't count on it being present) and comment your public interface well.
For libraries, I find that Doxygen works the best. Documentation is very important, it surely influences my choice of library to use for any given task.
Really, again, check out the app checker, its going to give you portability problem reports that would take a year of having the library out in the wild to obtain otherwise.
Finally, try to make your library easy to drop 'in tree', so I don't have to statically link against it. As I said, it could take a couple of years before it becomes common in most distributions. Its much easier for me to just grab your code, drop it in src/lib and use it, until and if your library is common. And please, please .. give me unit tests, TAP (test anything protocol) is a good and portable way to do that. If I hack your library, I need to know (quickly) if I broke it, especially when modifying it in tree or en situ (if the DSO exists).
If you'd like to help your users by giving them compiled code, the best way I know is to give them a statically linked binary + documentation how they can run the binary. (This is possibly in addition to giving the source code to them.) Most statically linked binaries work on most Linux distributions of the same architecture (+ 32-bit (x86) statically linked binaries work on 64-bit (amd64)). It is no wonder Skype provides a statically linked Linux download.
Back to your library question. Even if you are in an expert in writing shared libraries on Linux, and you take your time to minimize the dependencies so your shared library would work on different Linux distributions, including old and new versions, there is no way to ensure that it will work in the future (say, 2 years). You'll most probably end up maintaining the .so file, i.e. making small modifications over and over again so the .so file becomes compatible with newer versions of Linux distributions. This is no fun doing for a long time, and it decreases your productivity substantially: the time you spend on maintaining the library compatibility would have been much better spent on e.g. improving the functionality, efficiency, security etc. of the software.
Please also note that it is very easy to upset your users by providing a library in .so form, which doesn't work on their system. (And you don't have the superpower to make it work on all Linux systems, so this situation is inevitable.) Do you provide 32-bit and 64-bit as well, including x86, PowerPC, ARM etc.? If the .so file works only on Debian, Ubuntu and Red Hat (because you don't have time time to port the file to more distributions), you'll most probably upset your SUSE and Gentoo users (and more).
Ideally, you'll want to use GNU autoconf, automake, and libtool to create configure and make scripts, then distribute the library as source with the generated configure and Makefile.in files.
Here's an online book about them.
./configure; make; make install is fairly standard in Linux.
The root of the problem is that Linux runs on many different processors. You can't just rely on the processor supporting x86 instructions like Windows does (for most versions: Itanium (XP and newer) and Alpha (NT 4.0) are the exceptions).
So, the question is, how to develop shared libraries for Linux? You could take a look at this tutorial or the Pogram Library Howto.
I know what you are asking. For Windows, MSFT has carefully made the DLLs all compatible, so your DLLs are usually compatible for almost every version of Windows, that's why you call it "portable".
Unfortunately, on Linux there are too many variations (and everyone is thinking to be "different" to make money) so that you cannot get same benefits as Windows, and that's why we have lots of same packages compiled for different distributions, distro version, CPU type, ...
Some say the problem is caused by (CPU) architecture, but it is not. Even on same arch, there's still different between distributions. Once you've really tried to release a binary package, you would know how much hard it is - even C runtime library dependency is hard to maintain. Linux OS lacks too much stuff so almost every services involves dependency issue.
Usually you can only build some binary that is compatible to some distribution (or, several distributions if you are lucky). That's why releasing Linux programs in binary always screwed up, unless bound to some distro like Ubuntu, Debian, or RH.
Just putting a .so file into /usr/lib may work, but you are likely to mess up the scheme that your distro has for managing libraries.
Take a look at the linux standard base - That is the closest thing you will find to a common platform amongst linux distros.
http://www.linuxfoundation.org/collaborate/workgroups/lsb
What are you trying to accomplish?
Tinkertim's answer is spot on. I'll add that it's important to understand and plan for changes to gcc's ABI. Things have been fairly stable recently and I guess all the major distros are on gcc 4.3.2 or so. However, every few years some change to the ABI (especially the C++ related bits) seems to cause mayhem, at least for those wanting to release cross-distro binaries and for users who have gotten used to picking up packages from other distros than they actually run and finding they work. While one of these transitions is going on (all the distros upgrade at their own pace) you ideally want to release libs with ABIs supporting the full range of gcc versions in use by your users.