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).