[CMake] C++ Exceptions, C sources & MSVC80
Nicolas Tisserand
nicolas.tisserand at gmail.com
Tue Apr 8 10:30:28 EDT 2008
Hi CMakers,
I have a CMake project where C and C++ sources are compiled and linked
in the same target (a static library).
The default setting of the generated Visual C++ 2005 projects is to
enable C++ exceptions for C++ code and disable it for C code (/EHsc,
see below).
However, I need to change this flag to /EHs for the C sources, but
cannot manage to make it work with MSVC80 the way I successfully did
for the makefile and XCode generators (adding a C-specific flag to the
CMAKE_C_FLAGS variable for a mixed C/C++ target).
A minimal project exhibiting the behavior can be found below.
This has to be configured against CMake 2.4.8 using the Visual Studio generator.
# CMakeLists.txt ===============================================================
project(Exceptions)
IF (CMAKE_COMPILER_IS_GNUCC)
SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions")
ELSEIF(MSVC71 OR MSVC80)
SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /EHc-")
ENDIF (CMAKE_COMPILER_IS_GNUCC)
# The previous flags won't be reflected in the generated VC 8.0 project.
# This is a real pity, because optimized builds of the resulting program will
# crash.
# The crash occurs because the catch clause is optimized away.
# The catch clause is optimized away because the corresponding try
# block contains only one C function call which is considered non-throwing.
# The C function call which is considered non-throwing because cl.exe is invoked
# with /EHsc, which implies that all extern C functions are non-throwing.
# See: http://msdn2.microsoft.com/en-us/library/1deeycx5(VS.80).aspx for the
# /EHs, /EHsc and /EHc- flags.
# And: http://msdn2.microsoft.com/en-us/library/wfa0edys.aspx for the
# implications of using /EHsc on C translation units.
# (see the table at the bottom of the page)
add_executable(exceptions
exceptions.cpp
lib.h
lib.c
)
#===============================================================================
// lib.h =======================================================================
#ifndef LIB_H
#define LIB_H
#ifdef __cplusplus
extern "C"
{
#endif
typedef void (*ErrorHandler) ();
void libFunction (ErrorHandler errorHandler);
#ifdef __cplusplus
};
#endif
#endif
//==============================================================================
// lib.c =======================================================================
#include "lib.h"
void libFunction (ErrorHandler errorHandler)
{
errorHandler();
}
//==============================================================================
// exceptions.cpp ==============================================================
#include "lib.h"
#include <iostream>
struct Error
{};
static void errorHandler ()
{
throw Error();
}
int main ()
{
try
{
libFunction(errorHandler);
}
catch (Error&)
{
std::cout << "Error caught." << std::endl;
}
}
//==============================================================================
Maybe there is an easier way to obtain the behavior I am seeking, for
instance flagging the C sources as C++ code.
Any ideas on how to achieve that or anything else :-) ?
--
Nicolas
More information about the CMake
mailing list