mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
456 lines
24 KiB
Text
456 lines
24 KiB
Text
TheIDE Builder overview
|
|
See your 'distribution'. There should be "examples" directory and "uppsrc" directory. I am still developing the right terminology, but let us call these directories "nest".
|
|
Package is basically a directory containing source files. Package can have defined dependency on other packages.
|
|
Nest contains subdirectories with packages.
|
|
When you start TheIDE, you can choose (in the left area) something that we probably will call "assembly" (you can see "examples" and "uppsrc").
|
|
Assembly is related but not equal to the nest. In fact, assembly is an ordered set of one or more nests. When you select assembly (at TheIDE startup), you can see all "main" packages of first nest of assembly. "Main" package is one that has configuration(s) for building target(s). Each package defines what other packages it uses.
|
|
And now things get funny - when searching for dependent packages, TheIDE searches nests of assembly from first to last until it finds right package.
|
|
Now this has some advantages: In our development, we have e.g. uppsrc and uppstable nests containing almost identical packages. "uppsrc" is something like development sandbox, "uppstable" is a little bit conservative version. Now some "production" code I keep in "cxlsrc" nest, but I have two assemblies: cxlsrc: "cxlsrc;uppsrc" and cxlstable: "cxlsrc;uppstable". This way I can easily change from stable to development setup and back...
|
|
Well, back to includes. What TheIDE does is that it adds nest directories to the beginning of include path (using compiler commandline options). That way any source can refer to any other package include, using name of other package, like
|
|
#include <Core/Core.h>
|
|
(Note that this will include "uppsrc/Core/Core.h" in my cxlsrc assembly and "uppstable/Core/Core.h" in my cxlstable).
|
|
Include files are kept with sources this way and any manipulation is extremely easy - whole package is always contained in a single directory.
|
|
Each main package has associated one or more configuration.
|
|
It is basically a set of identifiers like
|
|
MSC DEBUG WIN32 ST GUI
|
|
Above means "use MSC compiler, build debug mode, single threaded, WIN32 GUIapplication".
|
|
Some of these flags are predefined and eventually detected by TheIDE builder, but you can add your own at your will. These flags can be tested by package and linker and compiler options added according to them, additional libraries added and so on (see "Workspace/Package Organizer...".
|
|
Moreover,these options are reflected in complied sources as defined macros (in this case flagMSC, flagDEBUG, flagST, flagGUI, flagWIN32).
|
|
Now there are two kinds of options: ambient and dotted. Ambient options reflect in all compiled packages. Dotted are introduced by '.' (like GNU LINUX ST GUI .XFT - XFT is dotted) and reflect only in main package (unconditionally) and in packages that accept them (this is mainly to reduce size of outputdirectory).
|
|
BTW, have I mentioned that you can use main package as non-main ? That way it is possible to add package testing code to it and use #ifdef flagMAIN to compile it only if package is used as main (for development reasons).
|
|
You can also define custom build steps based on file's extension(see "Workspace/Custom steps.."). Note that custom steps are associated with packages and conditioned by configuration.
|
|
Example is compilation of .RC files, which is associated with CtrlCore package and conditioned to Windows/MSC compiler. That means that as long as your main package depends on CtrlCore (directly or indirectly) and you are building Win32 app, .rc files get translated (anyway, another thing is that upp does use .rc files only to define program icon and just because there is not other way how to do it :).
|
|
|
|
=======================================================================================
|
|
|
|
Creating a new application
|
|
In this example we will create a simple "Hello world" application which contains two packages, called Main and Util.
|
|
U++ requires that we store our source files under a root directory called a nest. The nest directory will contain other directories that will hold the source files. The directories contained in the nest directory will become package directories as we create our application.
|
|
U++ requires one of our packages to be a main package. We will see shortly how to create a main package.
|
|
Start TheIDE. A dialog will appear titled Select main package. A list of assemblies appears on the left. Right click over the list of assemblies and select New assembly.
|
|
A dialog will appear titled Assembly setup. First, give the assembly a name in the field titled Assembly name. A good choice is the name of the application, which we will call "Hello".
|
|
Next, provide a list of nest directories in the field titled Package nests. The first directory must be the directory we want to contain the application's files. If you needed to use packages stored elsewhere, you would provide the names of the nests that contain them, separating the name of each directory with a semi-colon.
|
|
We don't want to do this, so you should only provide the name of our application's source nest. So in the Package nest field, type "c:/Hello".
|
|
The two other fields in this dialog can be left with their default settings. Exit the dialog by clicking the OK button.
|
|
At this stage, U++ will have created the nest directory "c:/Hello". We now want to create two packages called Main and Util. Click on the New button to start the Create new package dialog and give the package the name "Main" . TheIDE will start, showing package Main at the top left of the display.
|
|
We now want to make Main a main package, because it is this package that must produce our target application. Right click on Main and select Main package configuration or select Workspace|Main package configuration... through the menu bar.
|
|
Now let's create package Util and add it to package Main.
|
|
|
|
========================================================
|
|
|
|
> How can I switch between mingw and vc71 builds ?
|
|
|
|
Well, depends. If you have installed regular upp release to machine with
|
|
already installed MSC71, all you have to do is to click to left "drop down"
|
|
button of toolbar combo displaying output mode - and switch from "GCC DEBUG"
|
|
to "MSC71 debug".
|
|
|
|
> In dir "out\Core\MINGW-CONSOLE-GCC-MSC-OPTIMIZE-RELEASE-ST-WIN32-WIN32",
|
|
> what means "MSC" ?
|
|
|
|
Sorry, outdated package (it is that NTL export package I sent you, is not it
|
|
?). Just edit main config and replace config by simple "GUI ST" (GUI
|
|
SingleThreaded application - rest is set in output mode).
|
|
|
|
========================================================
|
|
|
|
> I also find using Doc++ quite slow. I think there need to be some keyboard
|
|
> shortcuts for applying "in-line" formatting such as bold;
|
|
|
|
Ctrl+B
|
|
|
|
> Some more fonts would be good as well.
|
|
|
|
Well, there is a good reason for staying with that limited set - platform
|
|
portability. I can easily provide Arial/Times New Roman/Courier equivalents
|
|
on Linux, but any other font would cause a problem....
|
|
|
|
========================================================
|
|
|
|
> I suggest that I create a plan for the documentation of theIDE. This will
|
|
> need to reflect the way that documentation is organised in upp but because
|
|
I
|
|
> don't yet understand that, I'll start with some headings. Something like
|
|
>
|
|
> Location Contents
|
|
> ===================================================
|
|
> AppDoc/IDE/Overview Brief overview: what upp is for
|
|
> AppDoc/IDE/Getting started Getting started
|
|
> AppDoc/IDE/Concepts Packages, assemblies, nests, ...
|
|
> AppDoc/IDE/Build The build process
|
|
> ...
|
|
> ===================================================
|
|
|
|
I think that you already got a clue about "Location" - this seems all right
|
|
to me.
|
|
|
|
Just to explain a little bit more about Doc++ system - each package has
|
|
"doc.dpp" directory, in which are contained various text resource files that
|
|
are coupled with package. These resources are organized _across_ packages
|
|
in three-level structure, using "namespace", "nesting" and "item".
|
|
|
|
When Doc++ is used to document C++ sources (one of possible uses),
|
|
"namespace" corresponds (no wonder) to C++ namespace, "nesting" corresponds
|
|
to struct/class/union (or is "<global>") and "item" is description of
|
|
method, data declaration, function etc. Sometimes, however, item is just a
|
|
link to other resource, typically class is documented in single document and
|
|
methods are realized as links to it.
|
|
|
|
Anyway, in this moment you will likely work with "external" documents, these
|
|
are documents that are unrelated to concrete C++ elements - like application
|
|
docs etc... Still they follow same main organization.
|
|
|
|
As all text resources are kept inside package directories and their format
|
|
is maintained in a way that makes converting them into C++ quite easy, it is
|
|
very easy to "get" them into actual application. Usually it involves
|
|
selecting the namespace you want to include into C++ application and
|
|
performing #include - see "ide" package, "About.cpp" file to see how that
|
|
can be done. Well, this is not something you would absolutely need to know
|
|
to write docs, but it will certainly help to understand how things are
|
|
organized.
|
|
|
|
Important note - as writing docs using Doc++ stores text documents inside
|
|
these directories as described above, uninstalling U++ package would delete
|
|
them! So you better backup before it, or maintain separate nest for uppsrc
|
|
(like uppsrcdev) outside of distribution directory.
|
|
|
|
========================================================
|
|
|
|
BTW, it is not so uncommon that certain package can be used both as main or
|
|
not-main (we should forge some term for non-main packages...) . One example
|
|
is adding debuging sources, so that when compiled as main, those sources are
|
|
included and run, otherwise package is used and test code is not needed
|
|
anymore. Or, for some reasons, whole standalone application can be included
|
|
in another application.
|
|
|
|
========================================================
|
|
|
|
Please, do not use html format for email, as it makes quoting and replying
|
|
somewhat difficult... I will use ">>>>>" for distringusihing yours and mine
|
|
text...
|
|
|
|
>>>>
|
|
I haven't yet discovered everything about what Ultimate++ is. I'm
|
|
concentrating on packages/assemblies at the moment. I've read your
|
|
documentation, but I haven't understood it.
|
|
|
|
I get the impression from the example applications that one of the things
|
|
Ultimate++ offers is an application framework: a set of classes that can be
|
|
used to build applications. Assuming that's the case, does this feature need
|
|
a name (ultimate application framework/UFC/UAF)?
|
|
<<<<
|
|
|
|
Actually, framework is named "Ultimate++". You can also consider TheIDE as
|
|
part of framework - in the end, it is nothing else than a (main) package...
|
|
|
|
>>>>
|
|
Leaving aside how packages, nests and assemblies are implemented, this is
|
|
what I know - or think I know - about them. Perhaps you could add to this
|
|
and correct anything I've got wrong.
|
|
packages are containers
|
|
<<<<
|
|
|
|
Well, it could be said so. Simply put, package is a directory (which IS a
|
|
container) that contains related files. When compiled, it turns to library.
|
|
It is also important that package files are ALWAYS stared only in that
|
|
directory - so (re)moving package etc. is quite easy.
|
|
|
|
>>>>>
|
|
packages can contain source files and other packages
|
|
<<<<<
|
|
|
|
It can contain source and other kinds of files (including that text
|
|
resources contained in upp directory). It does NOT CONTAIN other packages -
|
|
but it can use them (be dependent on them).
|
|
|
|
>>>>
|
|
a "main" package contains everything needed to build an executable or a
|
|
library. If the package builds an executable, it will have a "main" function
|
|
<<<<
|
|
|
|
This is mostly correct. The main package really compiles to the
|
|
application - and it has some kind of "main" function.
|
|
|
|
I think that we can explain it on some example:
|
|
|
|
See examples/AddressBook. Now AddressBook is main package. If you would open
|
|
"Package organizer", you should see that it uses "CtrlLib" package (it
|
|
contains most GUI widgets). "CtrlLib" package uses "CtrlCore" (contains
|
|
basic widget functionality), "CtrlCore" uses "Draw" (contains Drawing
|
|
routines) and Draw uses "DocTypes" (contains some formating) and "Core"
|
|
(contains containers, streams, string etc.).
|
|
|
|
So in other sense, main package is a root of hierarchy too.
|
|
|
|
Now the important part is that what package "uses" is always described in
|
|
package itself. That means that when I was creating AddressBook, I have
|
|
added only CtrlLib - and rest packages where added indirectly. Also, when
|
|
DocTypes will become obsolete and replaced by RichText package (which
|
|
actually is a plan :), I will only change "uses" of Draw package - and
|
|
DocTypes will be replaced across ALL applications.
|
|
|
|
Purpose of all this mess is that I want to have packages logically grouped.
|
|
I disliked "old" times with Visual C++, when I needed to add sets of
|
|
libraries for related applications all over again.
|
|
|
|
I recommend you also to browse through distribution directories and examine
|
|
what files are included, and eventually see contents of ".upp" files (these
|
|
are package description files). TheIDE normally takes care about them, but
|
|
knowing about them gives a lot of hints.
|
|
|
|
>>>>
|
|
a "main" package has one or more configurations that provide information
|
|
about what is being built, etc.
|
|
<<<<<
|
|
Correct.
|
|
|
|
>>>>>
|
|
an assembly is an ordered set of packages
|
|
<<<<<
|
|
|
|
Incorrect. Assembly is an ordered set of nests (or whatever new term we will
|
|
find). Nest is a directory that contains packages.
|
|
|
|
E.g. imagine you want to work on refactoring CtrlLib package - e.g. you
|
|
would want to improve MenuBar, but not to change anything else than CtrlLib
|
|
package and want to have older version still available (because work is long
|
|
and you might need to build some other application with original CtrlLib
|
|
meanwhile). Now you might do following: Create new nest directory
|
|
|
|
c:/dev-uppsrc
|
|
|
|
and new assembly "dev-examples"
|
|
|
|
c:/upp/examples;c:/dev-uppsrc;c:/upp/uppsrc
|
|
|
|
and copy c:/upp/uppsrc/CtrlLib to c:/dev-uppsrc
|
|
|
|
Now when you will load "dev-examples"/Menu, TheIDE will load Menu from
|
|
c:/upp/examples, CtrlLib from c:/dev-uppsrc and rest of packages from
|
|
c:/upp/uppsrc (whenever it does not find a package in first nest directory,
|
|
it tries to search it in next etc...)
|
|
|
|
That was pretty complicated example, so what about something simpler - you
|
|
want to use U++ to develop some application, but you will likely not want to
|
|
put your package(s) to distribution's "uppsrc" nest - so you will probably
|
|
create something like
|
|
|
|
c:\MyUppApps
|
|
|
|
and "MyApps" assembly
|
|
|
|
c:\MyUppApps;c:\upp\uppsrc
|
|
|
|
This way you will have your package in separate nest directory, but still
|
|
will be able to use all "uppsrc" packages. (BTW, in next distribution(s),
|
|
something like "MyApps" will be created by install process...)
|
|
|
|
===================================================
|
|
|
|
PACKAGE ORGANISER DIALOG
|
|
> I notice references to symbols such as WIN32. Are these set by the system
|
|
or
|
|
> by the user? I can see some correspondence between symbols and options in
|
|
> the dialog "Main package configuration(s)/Configuration flags".
|
|
|
|
That is correct. Time to describe: What you setup in main package
|
|
configuration are basic compilation flags (typically, it is GUI vs. CONSOLE
|
|
and MT vs. ST (single/multithreaded). Anyway, you can also add any
|
|
"user-defined" flags not generated or recognised by build system.
|
|
|
|
When you start building, build system complements these flags with some
|
|
other, like WIN32 for target, DEBUG meaning debug mode, level of debug mode
|
|
(DEBUG_MINIMAL, DEBUG_FULL), MSC71 for compiler type, BLITZ indicating
|
|
blitz-build etc. When building main package, MAIN is added.
|
|
|
|
Thinking about it, we should introduce new terms "main package
|
|
configuration" and "effective configuration" here.
|
|
|
|
All these flags then condition build. Some of them are understand by
|
|
builders (by builder I mean compiler specific code to build target), all are
|
|
reflected as flagXXXX macro defines in sources, so that you can use #ifdef
|
|
to exclude/include parts of sources based on effective configuration.
|
|
|
|
Now look at the "out" directory - that should help you understand how
|
|
specific intermediate files are stored based on sorted set of compilation
|
|
flags.
|
|
|
|
> In the Package organiser dialog, what is the "Accepts" property for?
|
|
|
|
User flags can be "dotted", e.g. ".XFT". These flags reflect only in main
|
|
package (always) and then just in packages that have these flags listed in
|
|
"Accepts" property. This is mainly to reduce the size of "out" directory.
|
|
|
|
> Could I try you out on the purpose of the "When" tables?
|
|
|
|
Well, now during compiling, you often need to add some additional
|
|
informations like libraries etc. for package - but apparently there are not
|
|
same libraries on Linux and Windows, or there are other reasons to add/not
|
|
add specific libarry. So you can condition adding library (or anything else)
|
|
by that "When" column. Format is simple - all flags not prepended by "!"
|
|
must be present, "!" must not... Like "LINUX !XFT" will be valid only if
|
|
LINUX is in effective configuration and XFT is NOT in effective
|
|
configuration.
|
|
|
|
> o I assume that "When/Additional libraries", "When/Compiler options" and
|
|
> "When/Linker options" have the obvious meanings. Examples seem to confirm
|
|
> this.
|
|
|
|
Yes :)
|
|
|
|
> o "When/Add or remove flag(s)". Is the purpose to define equivalences? I
|
|
> notice one example When==NOTMFC, Add or remove flag(s)==!GUI !CONSOLE.
|
|
Does
|
|
> this mean "if NOTMFC is set, unset GUI and CONSOLE"?
|
|
|
|
Yes. In when, as described above, "!" means not present, in add/remove it
|
|
means remove.
|
|
|
|
> o "When/Target file override". I haven't seen any examples. What's it for?
|
|
|
|
Well, it is somewhat obsolete now. You could use it to override target file
|
|
of compilation (either .lib for sub-package or .exe for main package),
|
|
anyway you can do the same thing in the "Build.." pane.
|
|
|
|
Note to TOMAS: Do you think we should remove "Target file override" ?
|
|
|
|
> PACKAGES
|
|
> I think it's the case that a newly created package will not appear in its
|
|
> assembly's list of packages until it's been given a main package
|
|
> configuration. Is that correct?
|
|
|
|
It is correct for main package select dialog (one that appears upon startup
|
|
of TheIDE) - but you can set "All modules" (damn it, should be "All
|
|
packages" ) to see it. Only package with main config is considered main.
|
|
|
|
Anyway, when adding package to "uses", you should see all packages.
|
|
|
|
> I spent a long time trying to add a new
|
|
> package to an assembly and puzzling over why it didn't appear when I next
|
|
> tried "Set main package".
|
|
|
|
Sorry:) Right today I finished system of package templates that should do
|
|
this for you automagically...
|
|
|
|
===================================================
|
|
Summary of packages:
|
|
|
|
Core - core components, like streams, string, containers etc...
|
|
CtrlCore - basic GUI widget functionality, including X11 and Win32 interfaces
|
|
CtrlLib - standard library of GUI widgets
|
|
DocTypes - typesetting and documents, including Qtf. In future, it is planed to be obsoleted by RichText.
|
|
Draw - drawing routines, including X11 and Win32 interfaces
|
|
Esc - ESC scripting language interpreter (Embedded SCripting language)
|
|
Geom - advanced FP geometry and graphics
|
|
Image - advanced raster image operations (bilinear rescaling etc...)
|
|
MySql - MySQL interface
|
|
Ole - some OLE routines (TOM, please specify :)
|
|
OleDB - OLE DB interace (dtto)
|
|
Oracle - Oracle interface
|
|
Plugin - contains packages for working with bz2, gif, jpeg, png, tiff, zim and zlib formats.
|
|
RichEdit - wordprocessor
|
|
RichText - data model for wordprocessor - scheduled to replace DocTypes when support for tables is added
|
|
Sql - basic SQL functionality
|
|
SqlCommander - application: SQL console
|
|
SqlCtrl - SQL GUI widgets
|
|
TCore, TDraw, TCtrlLib, TSql - can be considered as "candidate" packages
|
|
Updater - automatic exe deployment application
|
|
Web - html, TCP/IP and remote process support
|
|
|
|
Parts of TheIDE:
|
|
|
|
Browser - Doc++ implementation
|
|
Builders - builders for GCC, MSVC and Java
|
|
Debuggers - GDB visual interface
|
|
Docpp - simple C++ parser for documentation purposes
|
|
IconDes - raster image designer
|
|
ide - TheIDE main package
|
|
IdeEditor - source file editor
|
|
LayDes - layout designer
|
|
|
|
=========================================
|
|
> How to add a library at linktime ?
|
|
|
|
> I would like to add the OpenGL libraries at linktime
|
|
> libopengl32.a
|
|
> libglut32.a
|
|
> libglu32.a
|
|
|
|
Using package organizer. Just add opengl32, glut32 and glu32 to the package that uses them.
|
|
Open "Workspace"/"Package organizer".
|
|
|
|
You should see "Aditional libraries" pane - rightclick and add "opengl32 glut32 glu32".
|
|
For now ignore "When" column - you would want to use it for conditioning these libraries for e.g.
|
|
mingw build.
|
|
|
|
As libraries you mention are part of mingw (and this way are already on library path),
|
|
not further problem should appear. If they would be in some directory not already known to
|
|
TheIDE, you can add it in "Setup"/"Build methods".
|
|
|
|
==========================================
|
|
> b) How to get it into program so that Windows sees the icon. This one is a
|
|
> little bit more compilacated and indeed it requires creating .rc and
|
|
> converting icon to .ico format. In fact, this is the ONLY use for .rc left
|
|
> in Ultimate++ (we may even remove it later). To convert to .ico you can use
|
|
> some third-party tool, or you can setup ImageDes to do it for you
|
|
> automatically (somewhat not so logically, the option is in properties dialog
|
|
> of Image designer).
|
|
|
|
A little more on application icons: if Windows is to know about the
|
|
application icon, it must be stored as an icon resource. Under Windows 98,
|
|
first resource of icon type is taken, under Windows NT icon with lowest ID
|
|
is used (or vice versa, I'm not exactly sure now; however the icon
|
|
identification method differs a little among the various Windows clones, so
|
|
usually it's a good idea to keep the icon resource at the beginning of the
|
|
RC file and give it the lowest ID as well).
|
|
|
|
Another thing to keep in mind is that an ICON is actually a collection of
|
|
(masked) bitmaps - there can be a series of icons with different sizes and
|
|
color models (bit depths). Most commercial applications have at least a pair
|
|
of icons - large icon (32x32) and small icon (16x16). The large icon is
|
|
shown when you put your application on the desktop, in file explorer with
|
|
large icons on or when switching among applications using Alt+Tab. The small
|
|
icon shows on the taskbar, in the topleft corner of the application window,
|
|
in explorer in small icons mode and in other file management software like
|
|
winzip or Windows Commander.
|
|
|
|
Actually the above definition is not precise: the application window icon
|
|
and the icon on the taskbar are set programmatically, although usually they
|
|
display the same small application icon image. Therefore these two icons can
|
|
be set without any icon resources. The icon resources are needed only for
|
|
icons that are to be displayed from "outside", i.e. without any
|
|
programmatical cooperation from the application itself.
|
|
|
|
To setup RC for this purpose, you have to define an ICON resource, like
|
|
this:
|
|
|
|
5555 ICON DISCARDABLE "ide.ico"
|
|
|
|
(Borland resource compiler supports embedded icons with the binary contents
|
|
of the ICO file written as binhex directly into the RC file. Microsoft
|
|
resource compiler doesn't support this feature so the icon has to be kept in
|
|
a separate file. Usually it's easiest to have the icon in the same directory
|
|
as the resource. You can make the built-in image designer in IDE generate
|
|
this ICO file for you. In the setup dialog, the bottommost section
|
|
"Application icon" lets you enter the name of the desired ICO output file
|
|
and the image identifiers of the large (32x32) and small (16x16) application
|
|
icons. Naturally images with these names must exist in the IML file. You can
|
|
also select color format for the icon, which is usually 16 or 256 colors.
|
|
I'm not sure now but I'm afraid there are certain limitations concerning
|
|
color formats supported in various Windows versions. 16 and 256 should be OK
|
|
everywhere, I'm not very optimistic about hicolor and truecolor.
|
|
|
|
To make the long story short, first paint the large and small icon in the
|
|
image designer. Enter their names into the setup dialog together with the
|
|
ICO file name and put an ICON resource line (with the same file name) into
|
|
your RC. This should do for the application icon to start working.
|
|
|
|
Good luck
|
|
|
|
Tomas
|
|
|
|
==========================================
|
|
==========================================
|
|
==========================================
|
|
==========================================
|
|
==========================================
|