On Tue, 09 Jun 2009, Szak�ts Viktor wrote:
Hi,
> Currently our build system will only enable HB_DYNLIB
> for non-gcc/win compilers.
> Yet, I see these lines in include/hbdefs.h:
> ---
> #elif defined( __GNUC__ ) && defined( HB_OS_WIN )
> #define HB_EXPORT __attribute__ (( dllexport ))
>
> #elif defined( __GNUC__ ) && defined( HB_OS_LINUX )
> #define HB_EXPORT __attribute__ ((visibility ("default")))
> ---
> Which means HB_DYNLIB *has* some rules for gcc/win and
> even gcc/linux builds.
The visibility attribute allows to reduce number of public symbols and
it works on most of platforms which supports ELF format though I enabled
it only for Linux and used in my local builds. Maybe in the future it will
be commonly used and we can make it default for all *nix builds.
> Do we need these? When? Should we create a separate
> -DHB_DYNLIB build for MinGW for any reason?
MinGW has a feature which allows to automatically add export attribute
to all public symbols if non of them has such attribute explicitly set
when DLL is created. If at least one attribute is exported then it's
automatically disabled so programmer choice has the highest priority
and only programmer decides which symbols should be exported.
We are using this functionality to create harbour.dll from object and
libraries created for non exported static builds. It allows us to eliminate
one compilation phase but it's a hack which can cause some problems.
Code for dynamic libraries has to be relocatable. On some systems it means
that it will have to be a little bit less optimal (slower) then pure static
code. Usually if programmer wants to enable relocatable code he has to use
-fpic or -fPIC GCC switch. Anyhow on some systems (CPUs) most of generated
code is relocatable by default as long as some additional optimization
switches are not enabled. As I can see it happens in MinGW builds at least
for x...@32. Here we do not use any -fpic/-fPIC switches and we can create
fully functional harbour.dll. Anyhow it's possible that such functionality
will be lost in the future or even now cannot be used with some non default
optimization switches - I haven't make any deeper tests with current MinGW
builds on Windows so I do not know. In general we should keep support for
separate build phase which can be necessary to create shared library.
For sure it's necessary to use -fpic or -fPIC in most of *nixes except
Linux on x...@32 though even here some code constructions may force it.
Of course we can enable -fPIC as default switch (and we already does it
for some platforms because we do not have separate compilation phase for
shared libraries here) but it causes noticable performance reduction.
Depending on architecture from 0 (some CPUs can use only relocatable code)
to 20%. On x86 machines it is between ~5-10%. In general clean build for
shared library should export symbols and use -fPIC/-fpic switch.
In Windows there are two attributes: EXPORT and IMPORT.
The 1-st one causes that symbols are exported in public table which later
can be accessed to create bindings between executable and DLLs. It should
not effect directly generated code though indirectly it may interact with
some compiler logic, i.e. some optimizations can be bound with existence
of such attribute. IMPORT attribute has different meaning. It informs
compiler the symbol comes from external DLL or executable. It means that
compiler has to access such symbol indirectly by dynamic symbol table
and cannot make optimizations which needs link time bindings and offset
recalculations. It causes that slower code is generated but there is not
other way. The faster optimal code simply cannot work. It's extremely
important for structures. Without valid IMPORT attribute their members
cannot be accessed from external DLLs. It means that the same header files
should use EXPORT attribute when they are used to compiled base code which
should be replaced by IMPORT attribute when they are used by external DLL
code which want to use exported functions or structures. In fact for simple
functions it will work even if header files contain EXPORT attribute. But
for any constructions which needs offsets, f.e. structure members it won't
and valid IMPORT attribute is strictly necessary - otherwise compiler will
generate optimized code which cannot be used with dynamic DLL bindings.
Looks that in the past this knowledge was not known for [x]Harbour windows
developers and instead of fixing attributes in header files as workaround
for accessing some structures like hb_stack or hb_set functions like
hb_GetSetStructPtr() or hb_stack(). It was working but it was the less
efficient way. The same effect can be reached by using indirect pointer
items like and it was the reason why I added to xHarbour:
HB_SET_STRUCT * hb_set_ptr = &hb_set
and:
HB_STACK * hb_stack_ptr = &hb_stack;
Using them instead hb_set and hb_stack directly effectively resolves the
problem forcing the code like for structures declared with IMPORT attribute.
Anyhow it was also hack and the valid solution is introducing to header
files an option which allow to switch IMPORT/EXPORT attribute at least for
non-function symbols.
best regards,
Przemek
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour