The
-fvisibility=hidden and
-fvisibility-inlines-hidden options make all symbols hidden by default on GNU (and compatible) C++ compilers, respectively for regular symbols and inline functions and class member functions. These options are _required_ for all PixInsight modules and applications.
By default, all nonstatic symbols are made public by the standard compilers on UNIX/Linux. This includes FreeBSD, Mac OS X and Linux. This default behavior is very unfortunate because it leads to conflicts between symbols exported by multiple shared objects loaded by the same application, degrades execution performance due to the excessive overhead caused by huge symbol tables, and blocks important compiler optimizations. This is especially problematic for heavily modular applications like PixInsight. You have just experienced how obscure and complex these problems can be.
By contrast, the default symbol visibility has always been hidden on Windows. This is why you need to explicitly tell the linker which symbols are to be exposed publicly by a DLL, either through a
module definition file (.DEF), or by using special symbol attributes such as
__declspec(dllexport) and
__declspec(dllimport) in Visual C/C++. There are a few things---very few---where Windows development has been superior to UNIX, and this is clearly one of them. Fortunately, since version 4.0 GCC has the
-fvisibility=hidden and
-fvisibility-inlines-hidden options, which solve this problem efficiently. I suggest you pay a read at
this article on GCC's Wiki for more information on these options. If you really want to learn how to write good shared libraries on UNIX, reading
this document by Ulrich Drepper is necessary.
Besides the standard loadable module entry points (_fini, _info, _init), a PixInsight module on UNIX/Linux must export
exclusively the following three symbols:
IdentifyPixInsightModule
InitializePixInsightModule
InstallPixInsightModuleThese are the names of the public functions that a module provides for interaction with the PixInsight Core application. Test your module with the following command:
nm -D --defined-only <your-module-name>-pxm.so(replace <your-module-name> with your module's actual name). If it shows more defined symbols (prefixed with 'T') than the ones listed above, then you have a linkage problem and your module is not valid. For example, the latest version of the PixelMath module:
nm -D --defined-only PixelMath-pxm.soproduces the following output:
0000000000194df0 T IdentifyPixInsightModule
00000000001954d0 T InitializePixInsightModule
000000000009f1c0 T InstallPixInsightModule
0000000000449b14 A __bss_start
000000000044a968 B __gnu_lto_v1
0000000000449b14 A _edata
000000000044a970 A _end
00000000001b4df0 T _fini
0000000000035898 T _initMy general recommendation is to always generate makefiles and project files using the latest version of the Makefile Generator script in PixInsight. This ensures that your module will install and interact optimally with the PixInsight Core application. The script also applies the best set of compiler optimizations that we have tested thoroughly with the current PCL versions. For example, the version that comes with 1.8.0 RC2 (Makefile Generator 1.73) enables -Ofast optimization by default with GCC 4.6 and later for PCL 2.0.1. It also generates project files for Visual C++ 2012, which we support officially from now on.