C++/Writing free software for many users
I would like to write a few useful freeware
programs, including a database application creator. (Already done a proof of concept in JSP/MySQL).
I have become rather aware that there are other OS's besides Windows. Since I want to share the programs among the most number of users, how can write code that will run without the users having to install additional run-times and libraries? I am using Ubuntu 7.10 "Gutsy Gibbon", and have installed Java, Perl, gc++ , Gambas and Just Basic (on wine)
I was thinking writing for Windows, Linux, Fedora, Solaris and Mac.How would I test for the Mac without actually using one? Do you think it is worthwhile or should I share the code and let a Mac person compile it themselves? Remember I want to end up with a binary in all these platforms - just click and run .
Assuming you intend to re-write your code in C++ (why else would you be asking a C++ expert?), then the main ploy to use is to avoid linking with dynamic link libraries / shared object libraries (.dll or .so files) where ever possible. That is, if you have the option then use a static library version (.lib or .a files). Doing so means the code you use from such libraries will be placed in the binary executable file and not reside in the dynamic link / shared object library file, and thus reduce the need to have various additional library files installed (or that you have to ship with your product).
This can apply for example to main language libraries (e.g. the C/C++ library) and additional vendor specific libraries (such as the Microsoft MFC and ATL libraries), as well as third party libraries such as the Boost libraries. In such cases you will find you can choose from various builds of libraries - one of which dimensions of variance being whether its a static or dynamic library (another maybe multi or single threaded - if so then these days it is probably best to go for a library build with multithreading support).
However you may not have such a choice in all cases - it may be some library critical to your project is only available as a dynamic/shared library. In which case consider shipping your product with any additional dynamic/shared libraries required, if feasible. Whether this is so will for example depend on the redistribution terms of the dynamic/shared libraries concerned. You will also have to ensure that your main executable can locate and load the dynamic libraries you ship and that you do _not_ overwrite newer versions already installed with older versions that may ship with your product - e.g. by placing all such files in the main bin directory of your product.
Of course if you are writing a database creation tool then you will presumably require support installed for (some of) the database backend(s) your tool supports - MySQL, Postgres, Oracle, Sybase, MS SQL server, etc.
As to testing - well sorry but you cannot test your software on a system without such a system available, and yes a Mac is problematic as you cannot just create a Mac virtual machine on a PC as you can for the other operating systems (or at least for the X86 version of Solaris). So it may be a good idea to license your software under an open source license and host it possibly on a site such as SourceForge (http://sourceforge.net/
). Then you can try and get some Mac people interested and point them at the project pages. If your project proves popular then it may have people posting you patches for other systems they have got it to build on.
Which leads onto another set of points. Not only are the operating systems different but so are C++ compiler and library implementations. They all have different shortcomings and extensions to ISO standard C++ and different takes on certain aspects of the C++ language. Hence writing robust, modern, cross platform code in C++ can be - um - interesting to say the least.
To handle variations in operating system APIs use libraries that wrap and/or abstract from these low level details. Some examples are:
- Boost libraries (see http://www.boost.org/
) which include support for operating system
specific things such as file system, ASIO and networking, IPC, etc. as well as many useful libraries that extend the C++ standard library.
- wxWidgets (http://www.wxwidgets.org/
) a cross platform GUI framework
- ACE (http://www.cs.wustl.edu/~schmidt/ACE.html
) - for flexible cross platform communications biased services.
Of course any such libraries will have to be buildable and usable for all your target operating system / development tool chain combinations.
Alternatively you can roll your own. Either way I really urge you to relegate such differences to specific modules of your code and use them through such wrappers or abstractions. Then supporting a new platform should only require changes to these underlying wrappers of abstractions. You will find that a large divide will be between the UNIX/Linux/POSIX way and the Microsoft way.
To handle compiler / language library differences you will probably end up with configuration files for compilers (and possibly for operating systems) so you can tailor your code where necessary. You might like to look at how the above mentioned libraries handle such things.
Another area to look carefully at is that of internationalisation (i18n) and localisation (l10n). Although it would be nice to be able to say that we could just use UNICODE for all character, strings and text for all systems this in fact can be a right pain the fundament as
a) not all systems support UNICODE, and if they do some use wide characters of
16 bits (UTF-16) and others 32-bits (UTF-32)
b) not all byte input and output from / to consoles / terminals / DOS boxes use
UTF-8 - Microsoft systems' consoles for example still use code pages with an
ASCII 7-bit base.
c) not all system APIs / language support library facilities support UNICODE (i.e. wide
character) pathnames even if the underlying operating system / file system does.
d) there is not one universal method of handling (localised) message stores
e) the C++ standard library support for i18n and l10n, although quite good, is not
always as good or easy to use as it could be. Specifically the names used for
locales are operating system (and possibly compiler) specific.
f) terms and conditions for some useful libraries clash with those of some vendor's
tools and libraries such that they cannot be used together. GNU libraries with
Microsoft libraries for example; the very useful GNU libconv character conversion
library is a specific example of relevance here.
You will require a decent build process and automated set of unit tests that can be executed for every build environment. They should preferably be executed after every check in of code. Obviously this may not be possible if you are hosting your project externally on a site such as SourceForge. In such a case maybe do regular checkouts to build and test machines (or virtual machines). There should preferably be some method of failures being posted, logged, notified etc. e.g. via email and updates to web site pages.
When all is said and done it may be easier to just take the hit that your users have to have a JRE installed and continue to develop your tool(s) in Java. This would be especially true if you know Java quite well but have little experience of C++.
Whatever your situation I hope this has given you some pointers. If you require further explanation of any of the points I have made here then please ask further questions, follow up questions if appropriate.