====== Linking ======
It's usual to link against a library. Usually, the ''-L'' flag is used to define the path where to search the library, and ''-l'' is used to indicate which library to link against.
Under //MacOS// this works to, but you could have to link against a //framework//. For this use ''-F'' to give the path and ''-f'' to indicate the //framework//.
====== Global constructor/destructor ======
:!: The following occurs with //g++// compiler from //MacPorts//. The genuine //Xcode// compiler is **not** concerned by what is described in this section !
For things to do on a module before or after an executable or a dynamic library is running, I used following code.
class gcdtor
{
public:
gcdtor( void )
{
// Things to do on starting.
}
~gcdtor( void )
{
// Things to do when quitting.
}
};
static gcdtor GCDtor;
This works on //Linux//, //Windows//, but not always on //Mac//.
On //Mac//, it works for executables, but not for dynamic libraries. For this, you have to use something like :
__attribute__((constructor)) void gctor( void )
{
// Things to do on starting.
}
__attribute__((destructor)) void gdtor( void )
{
// Things to do when quitting.
}
But this does not work for a //Mac// executable. And also ''%%__attribute__((...))%%'' is specific to //g++//.
So, for an executable, you can use something like the first code, but for a //Mac// dynamic library, you have to use something like the second code.
I use some macros, like below, to define global destructors/constructors without bothering if they're compiled for //Mac// or not :
#if defined( MAC ) && defined( LIBRARY )
# define GCTOR( discriminator )\
__attribute__( ( constructor ) ) static void gctor##discriminator( void )
#else
# define GCTOR( discriminator )\
class gctor ## discriminator\
{\
public:\
gctor ## discriminator( void );\
};\
\
static gctor ## discriminator GCtor ## discriminator;\
\
gctor ## discriminator::gctor ## discriminator( void )\
#endif
#if defined( MAC ) && defined( LIBRARY )
# define GDTOR( discriminator )\
__attribute__( ( destructor ) ) static void gdtor##discriminator( void )
#else
# define GDTOR( discriminator )\
class gdtor ## discriminator\
{\
public:\
~gdtor ## discriminator( void );\
};\
\
static gdtor ## discriminator GDtor ## discriminator;\
\
gdtor ## discriminator::~gdtor ## discriminator( void )\
#endif
''MAC'' has to be defined when compiling for //Mac// and ''LIBRARY'' when building a dynamic library.
The ''discriminator'' parameter allows you to declare several global constructors/destructors if you give them different values for this parameter, like this.
GCTOR( mymodule )
{
// Things to do on starting.
}
GDTOR( mymodule )
{
// Things to do when quitting.
}
Yes, you can use the same //discriminator// for a constructor and a destructor, but not for 2 or more destructors or constructors (in the same compilation unit).
:!: Finally, this doesn't work either (with the g++ compiler from //MacPorts//) as it seems that, when using ''%%__attribute__((destructor))%%'', the object are not correctly instantiated (or not instantiated at all) when those //global constructor// functions are executed (i.e., an object member defined as a reference to another object, which is given as parameter of the constructor method of the owning object, has a ''this'' == ''NULL'').
====== 'clang++' crashing due to mixed file encoding ======
===== Problem =====
When //clang++// encounters a file with mixed encoding, it crashes with poor indications about the responsible file, like :
0 clang 0x0000000100c57bb2 main + 12932498
clang: error: unable to execute command: Segmentation fault: 11
clang: error: clang frontend command failed due to signal (use -v to see invocation)
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin11.4.2
Thread model: posix
clang: note: diagnostic msg: PLEASE submit a bug report to http://developer.apple.com/bugreporter/ and include the crash backtrace, preprocessed source, and associated run script.
clang: error: unable to execute command: Segmentation fault: 11
clang: note: diagnostic msg: Error generating preprocessed source(s).
Re-encoding files with //recode//, //iconv// or //Notepad++// does not solve the problem, even if the file looks, after re-encoding, correct.
===== Solution (doesn't really work) =====
NOTA : this solution seems to work when applied to not too much files. When //Xcode// had to handle too many files, it fails (it creates extraneous copies from the files prefixed with a dot, and the original files aren't handled). Regarding the amount of files //Xcode// could handle at once, it would me took too much time to handle all my files , so I used the other solution.
* Open all the files with mixed encoding with //Xcode//,
* select them in //Xcode//,
* ''File Navigator'' (be sure that the ''File name'' entry is set to ''Multiple Values'',
* select a ''Text Encoding'' which is used by none of you files (this is to force //Xcode// to handle all the files, or some files remain unchanged, even if they content mixed encoding),
* select the final ''Text Encoding'' (should be ''Unicode (utf-8)'' for //clang++//).
NOTA : the files are immediately converted, without having to save them explicitly.
===== Other solution =====
I ended by using the ''-c'' option of //iconv// (''iconv -c -t utf8 ...''). The drawback is that all non-ASCII characters are stripped, this affecting all my French comments. Here's the final script (handles all the ''.h'' and ''.cpp'' files in the current directory and its sub-directories) :
find . -name "*.h" -exec echo "cp \"{}\" \"{}.bak\";iconv -c -t utf8 \"{}.bak\" >\"{}\"" \; >script
find . -name "*.cpp" -exec echo "cp \"{}\" \"{}.bak\";iconv -c -t utf8 \"{}.bak\" >\"{}\"" \; >>script
. ./script
To verify if the files are correct :
find . -name "*.cpp" -exec iconv -t utf8 {} >/dev/null \;
find . -name "*.h" -exec iconv -t utf8 {} >/dev/null \;
===== Conclusion (intermediate) =====
Even with correct (ASCII-only) files, //Xcode// genuine compiler crashes way too often with the source code of my software components to be usable. Fortunately, one can use a //true// //g++// compiler instead.
===== Conclusion (final) =====
It appears that the problem was the //VMWare Player// shared folder. When the sources are on the local disk, and not on a shared folder, then the //Xcode// genuine compiler doesn't crash at all.
Remarkably enough, //g++// from //MacPorts// never crashed, even when the sources were on a //VMWare Player// shared folder. So, it seems that the //Xcode// genuine compiler has anyway a little flaw. But the //g++// from //MacPorts// is nearly unusable (see above).