Recently, I've started seeing some odd comparisons against Delphi that I had never really thought about before (or heard of), in places like the NUG or the forums. So when I noticed someone suggesting Delphi as an alternative to REALbasic because it built single file executables, I decided it was time to do some research and see what's up.
It turns out that Delphi builds single file executables in exactly the same manner that REALbasic does (as well as numerous other languages, like C and C++). What Delphi does *not* do is the same as what REALbasic does not do: it doesn't do any sort of magical hackery with plugins or external libraries to turn them into a single file executable. This is a key point, and that's what I want to talk about here.
Delphi has two different concepts for reusable code items: DLLs and BPLs. Everyone is familiar with a DLL, but for completeness sake, I'll discuss that first. You can access methods from a DLL in Delphi in much the same way as you can in REALbasic, and most other languages. Delphi doesn't have a Declare statement, per se, but they have their own equivalent. When you do the "Delphi Declare", what really happens is that you're creating a reliance on the target library for your application. So if your application cannot find that library at runtime, your application won't load. And that library exists on disk as a .DLL file. This isn't earth-shattering either; it's no different than declares.
Delphi has another concept for reusable code that's called a "Package." All packages live inside a .bpl file, which is basically a Delphi-specific library format. There are two ways you can make use of packages as a developer. You can either use a package at design time, or at run time -- either way results in the same functionality being exposed to your project. However, these two different use cases are the key to understanding the single file executable concept.
If you use a package at design time, then its contents are statically linked into your project. The analogy that REALbasic has is an encrypted module or class. In these cases, the compiler will take the code from the library, and include it into your build application.
If you use a package at run time, then it's contents are dynamically linked into your project. When this happens, the .bpl file must be provided at runtime, on the disk or the application will fail to launch. This is analogous to the concept of plugins in REALbasic, which behave in exactly the same way.
A key excerpt from about.delphi.com's discussion of this feature is:
When deploying an application that uses run-time packages, make sure that your users have the executable file as well as all the library (.BPL or .DLL) files that the application needs. If the library files are in a different directory from the .EXE file, they must be accessible through the user's Path (autoexec.bat). The best place would be in the Windows\System directory.
So while the nomenclature might be different between Delphi's packages and REALbasic's plugins, the effects are the same. Both languages have a way for you to package up reusable code in two different forms: static and dynamic. And if you chose dynamic, then you will not get a single file executable on Windows with no external reliances. However, in both languages, if you do not use the concept of a dynamic package/plugin/library, then you will end up with a single-file executable.
Long and short: I've seen no literature or evidence that Delphi is doing something special with regards to its dynamic plugin system to allow for single file executables. I think it's just been a slight misunderstanding of how the varying systems work, which hopefully has been cleared up now!
I don't know Delphi, but maybe people say that because you can do more than you can in RB without needing external DLLs or packages? In RB it's hard to avoid using ANY of the internal plugins (Appearance Pack at least!)
But you also wrote:
>If you use a package at design time, then its contents are statically linked into your
>project. The analogy that REALbasic has is an encrypted module or class. In these cases, >the compiler will take the code from the library, and include it into your build application.
Which to me reads that the programmer can chose that option to get a single file executable if they want it unless the code in a package is only Delphi source code as with RB encrypted classes ... but your description (statically linked) makes it sound like it is more than that. It sounds like with Delphi it would be possible to have plugin like code that gets included in the exe that way as long as it dues not need the system support DLL's do ( compatibility shims and such)
But then again I really don't know anything about this type of stuff so I may simple be displaying my ignorance.
- Karen
@Karen -- in my own experiences, there's almost never any need for internal plugins in REALbasic, especially appearance pak! The plugins which I *do* make use of are SSLSocket (which I am thankful for, since I don't want to add several MB to every RB project on the off chance it might require secure sockets), and on rare occasions, RegEx. But appearance pak? Really? The only thing in there that's even a native control on Windows is the up down arrows, and even those aren't implemented as a native control!
As for the static linking, that's the same thing in RB as using encrypted items. Delphi happens to use the same package format for their feature, but the behaviors are the same. It's not a plugin if it's something that's statically linked into your application. It's just code. ;-)
The analogy is not exactly accurate. There is a very important distinction, that's that a BPL in delphi is compiled Pascal/Delphi code. An encrypted module in RB is close as far as usage goes, but unfortunately misses the mark as it is relatively easy (from what I've been told) to crack an encrypted module, not that I've tried it. FTC doesn't have a demo version you can actually use in test projects because it is written in pure RB and therefore a demo version of the control can't be securely distributed in a form that could not be cracked and used for free.
If there were a more BPL like library format in RB - that is, just a block of compiled RB code that you can attach to a project and have statically compiled into the final binary, that'd be quite handy.
@Blueapples -- you are correct that the two are not exact copies of one another. From the compiler's perspective, they basically are (as are the end results), but the usages are different from a user's perspective. You are right that encrypted items are only meant to keep casual pirates at bay, and that compiled code would be a much better safety solution in the long run.
I wasn't attempting to extol the virtues of encrypted items (if you've been reading for many years, you'll probably notice that I rarely have anything nice to say about them, actually). I was merely pointing out that Delphi doesn't make single file executables when you use its runtime packages, just like REALbasic doesn't make single file executables when you use its plugins.
@Aaron Yeah, I understand. Just saying, can we please have pre-compiled modules/classes soon? ;-)
@Blueapples -- for varying definitions of "soon", sure! ;-)
I still don't know why RB's new set up with regard to single file executables is such a deal breaker. I always thought most people don't even open the applications folder anyway. The apps can be installed into the applications folder with an installer and the majority of users will not even being aware of any dlls. In fact I can't even recall when I last looked in the apps folder. Also, after looking through the Programs Files folder on windows, I see that most applications have dlls. I'm sure others have presented these same arguments but I had to get it out there.
I think one thing that was convenient was you could just send someone an EXE and they could save it and run it
No installer required
But, MS recommends installers and they are pretty much expected by Windows users
I'm sorry to ask the dumb question of the day, but i thought we were not able to build single file executables with RB on windows any more, not even when it is pure RB code (with or without encrypted modules or classes), since we get the application libs folder with it, that at least includes appearance pak.dll. Did I miss something? If I didn't, then would it be correct to say that delphi can compile single file executables if no external dll's are used, because it is using the windows platform controls for it's user interface, while RB can't do this because it needs to use it's own controls to be able to make consistent cross platform interfaces?
If i understand this explanation, then the solution to again getting a single file executable is: deliver the "internal plugins / DLL's" as encrypted modules. Should be not to hard i think as RS has the original source.;-)
Regards,
Andre
By Aaron BallmanAuthor Profile Page on August 29, 2008 6:20 PM
@Blueapples -- for varying definitions of "soon", sure! ;-)
I think he meant "pretty soon". Does that help? :-)
Regards,
Andre
@Dirk -- not a dumb question at all! You're understanding it slightly off. The only way you currently can get a Libs folder for Win32 applications is if you use plugins (internal plugins, such as ones used by BevelButton, RegEx or external ones like MBS, Einhugur, etc). If you aren't using plugins, then you do get a single file executable on Windows.
@Andre -- we don't have the source code to plugins, and even if we did, we can't just convert it into RB code automatically (that would be a neat trick indeed). Oh, and "pretty soon" helps for varying definitions of "pretty" as well as "soon." ;-)
Aaron,
I've been using Delphi for years. By default, the functionality provided by the BPLs get linked right into the project's executable. It's been a while -- it's my recollection that BPLs are accompanied by DCUs -- compiled Delphi code -- that gets statically linked into the executable.
There is an option, "Build with runtime packages" which, when enabled, causes Delphi to produce smaller executables and requires that the application have runtime access to the BPLs -- specially formatted DLLs.
This article describes this in some detail:
http://delphi.about.com/od/objectpascalide/a/bpl_vs_dll.htm
-Tom
Just for posterity, if you want something close to the old functionality of single EXE RB apps, you can use a self extracting executable that automatically runs the real RB app and deletes the DLLs after the app closes. A bit of a kludge but if it's really important to not have an installer and start-up time for the app isn't critical, then it's a workable solution.
-- we don't have the source code to plugins, and even if we did, we can't just convert it into RB code automatically (that would be a neat trick indeed).
You mean someone left the RS-building with the sourcecode in the pocket?
Just add a tiny feature: inline assembler, should make it a breeze. (ahum)
Regards, Andre
@Andre -- we don't own every plugin in the community. Sure, we could internalize all of our own plugins, which would promptly make your application sizes much larger. Or we could turn our own plugins into encrypted modules, which would mean spending an extremely large amount of time to add a lot of risk to functional code to solve a non-issue for the majority of our customers.
As for inline assembler.. well, I'm just going to leave that one alone I think.
For clarity's sake, since this topic still seems to be going on in the NUG: static lirbary > plugin in REALbasic, nor in Delphi. Plugin = Dynamic Library in both tools. So again, Delphi *does not* have single file executables when you use the Delphi equivalent of plugins. If you use a BPL as a static library, then you do get a single file executable. This is identical to REALbasic if your project uses an encrypted module.
Speaking as someone who has used Delphi since its inception- it was a great RAD tool that made standalone, native executables at a time when Visual Basic had its VBRunXYZ issues (which are now different .NET Runtime issues). That was a very big deal.
Both Delphi and REALbasic have superior deployment over .NET in my mind since there is no large system level runtime requirement. To take advantage of the latest .NET features in the latest Visual Studio, you always have to update your .NET runtime requirement to a version your users may or may not have installed.
Whatever mode you use Delphi or REALbasic in- you just make an installer and everything you need can be managed independent of system level runtime versions, and in a much smaller package.
What Delphi does right that REALbasic currently does not do, related to "single file executables" (but that's only a symptom, there are other good things about this):
-Precompiled library support
-Everything needed for basic controls (including "bevel button" styles. heh) and other basic runtime calls are written in Delphi itself- thus allowing most apps to just use precompiled Delphi libraries. The RB compiler seems more capable than ever of implementing even the basic classes in RB itself via OS declares.
-All of that runtime source code is included in the professional version. The license does not allow redistribution, but does allow learning, changing, and tweaking of the runtime library as a whole should a developer desire. Visual Studio 2008 now allows access to the source in the .NET class library as well.
On 'small' difference between Delphi and RB, regarding DLL is that you can write a .dll in Delphi, while (until now) you cannot write a plugin with RB. As far as I remember, you can also load yourself the .dll at runtime, when/if needed.
I switched from Delphi to RB on msWindows a few years ago when Borland seemed to have no more interest in developping their developper products, while asking 'stupid' price for the license ($1000+). There are still a few things that were great in Delphi and are still missing in RB (more controls, better internet components, a cleaner grid component, better support for printing,...) However, I'm not ready to switch back.
Delphi is, and i dont mean to sound harsh, quite different from realbasic. Most people believe that Delphi is just another high-level language. In reality, the delphi compiler is en-par with a C/C++ compiler. It also comes with a buildt in Assembler, allowing you to write time consuming sub's (called procedures) in pure x86 assembler.
As far as DLL libraries goes, you forgot to mention that you dont need to statically bind your application to a DLL. You can in fact write code that loads a dll, check the methods in the dll, and either reject or accept it. Im sure you can do this in realbasic as well (or at least in the future).
One of the truly strong points for delphi is it's openness. All high level features (the "rad" part) is written in delphi (just like Realbasic). You can also inspect the source code for all the classes that ship with delphi (the VCL).
But the downside of all the extra power Delphi has (and i havent mentioned things such as sets and runtime type-information) is that it is very windows native. Borland (now codegear) tried porting it to Linux (they are forbidden to go to the mac by Microsoft, old deal), but that marked is .. well, not the biggest cash cow around.
Personally, i would like to write code in FreePascal on the Mac, then use my .SO (same as .dll files on windows) with RealBasic! That would give me the best of both worlds. Low-leve access to everything, and high level excellence for the user experience.
All in all, Realbasic comes out as a good product. But to directly compare it to delphi is like saying Visual Basic is just as good as C/C++. It just is not true. You can code a basic compiler in Delphi.
@Jon -- I certainly realize the two languages are different from one another. ;-) I was merely pointing out that Delphi's equivalent of REALbasic plugins do not build a single-file executable, which is a statement I had seen others erroneously making.
Oh, and btw, you can easily write a BASIC compiler in REALbasic too (or any other compiler, for that matter).