From 31bdec208d2eff596e203831de61b4fa6ed5abfa Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 8 Mar 2016 21:29:34 +0100 Subject: [PATCH] [DEV] basic simple log lib --- elog/debug.cpp | 15 ++ elog/debug.h | 45 +++++ elog/log.cpp | 523 +++++++++++++++++++++++++++++++++++++++++++++++++ elog/log.h | 130 ++++++++++++ elog/logIOs.h | 20 ++ elog/logIOs.m | 17 ++ lutin_elog.py | 73 +++++++ 7 files changed, 823 insertions(+) create mode 100644 elog/debug.cpp create mode 100644 elog/debug.h create mode 100644 elog/log.cpp create mode 100644 elog/log.h create mode 100644 elog/logIOs.h create mode 100644 elog/logIOs.m create mode 100644 lutin_elog.py diff --git a/elog/debug.cpp b/elog/debug.cpp new file mode 100644 index 0000000..e600123 --- /dev/null +++ b/elog/debug.cpp @@ -0,0 +1,15 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include + +int32_t elog::getLogId() { + static int32_t g_val = elog::registerInstance("elog"); + return g_val; +} + diff --git a/elog/debug.h b/elog/debug.h new file mode 100644 index 0000000..6112f69 --- /dev/null +++ b/elog/debug.h @@ -0,0 +1,45 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace elog { + int32_t getLogId(); +}; + +#define ELOG_BASIC(info,data) ELOG_BASE(elog::getLogId(),info,data) + +#define ELOG_PRINT(data) ELOG_BASIC(-1, data) +#define ELOG_CRITICAL(data) ELOG_BASIC(1, data) +#define ELOG_ERROR(data) ELOG_BASIC(2, data) +#define ELOG_WARNING(data) ELOG_BASIC(3, data) +#ifdef DEBUG + #define ELOG_INFO(data) ELOG_BASIC(4, data) + #define ELOG_DEBUG(data) ELOG_BASIC(5, data) + #define ELOG_VERBOSE(data) ELOG_BASIC(6, data) + #define ELOG_TODO(data) ELOG_BASIC(4, "TODO : " << data) +#else + #define ELOG_INFO(data) do { } while(false) + #define ELOG_DEBUG(data) do { } while(false) + #define ELOG_VERBOSE(data) do { } while(false) + #define ELOG_TODO(data) do { } while(false) +#endif + +#define ELOG_HIDDEN(data) do { } while(false) + +#define ELOG_ASSERT(cond,data) \ + do { \ + if (!(cond)) { \ + ELOG_CRITICAL(data); \ + assert(!#cond); \ + } \ + } while (0) + + diff --git a/elog/log.cpp b/elog/log.cpp new file mode 100644 index 0000000..28ab754 --- /dev/null +++ b/elog/log.cpp @@ -0,0 +1,523 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef ELOG_BUILD_ETHREAD + #include +#endif +#include +#include +#include + +#if defined(__TARGET_OS__Android) +# include +#endif + +#include + +#if !defined(__STDCPP_LLVM__) && defined(__TARGET_OS__Linux) && defined(DEBUG) + #include + #include + #include + #define MAX_DEPTH (256) + void elog::displayBacktrace(bool _breakAtEnd, int32_t _removeElement) { + // retrieve call-stack + void * trace[MAX_DEPTH]; + int stack_depth = backtrace(trace, MAX_DEPTH); + + ELOG_ERROR("Back-trace : "); + for (int32_t i = 1; i < stack_depth; i++) { + Dl_info dlinfo; + if(!dladdr(trace[i], &dlinfo)) { + break; + } + const char * symname = dlinfo.dli_sname; + int status; + char * demangled = abi::__cxa_demangle(symname, nullptr, 0, &status); + if(status == 0 && demangled) { + symname = demangled; + } + if (_removeElement <= 0) { + ELOG_WARNING(" " << dlinfo.dli_fname << ": "); + ELOG_ERROR(" " << symname); + } + _removeElement--; + if(demangled != nullptr) { + free(demangled); + } + } + if (_breakAtEnd == true) { + assert(false); + } + } +#else + void elog::displayBacktrace(bool _breakAtEnd, int32_t _removeElement) { + #ifdef DEBUG + assert(false); + #endif + } +#endif + +#ifdef DEBUG + #define DEFAULT_LOG_LEVEL elog::logLevelInfo + #define DEFAULT_LOG_COLOR true + #define DEFAULT_LOG_LINE true + #define DEFAULT_LOG_THREAD_ID true + #define DEFAULT_LOG_THREAD_NAME true + #define DEFAULT_LOG_CLASS true + #define DEFAULT_LOG_TIME true + #define DEFAULT_LOG_LIB_NAME true +#else + #define DEFAULT_LOG_LEVEL elog::logLevelNone + #define DEFAULT_LOG_COLOR false + #define DEFAULT_LOG_LINE false + #define DEFAULT_LOG_THREAD_ID false + #define DEFAULT_LOG_THREAD_NAME false + #define DEFAULT_LOG_CLASS false + #define DEFAULT_LOG_TIME true + #define DEFAULT_LOG_LIB_NAME true +#endif + +enum elog::level& getDefaultLevel() { + static enum elog::level g_val = DEFAULT_LOG_LEVEL; + return g_val; +} + +size_t& getFunctionSizeLog() { + static size_t g_val = 5; + return g_val; +} + +size_t& getThreadSizeLog() { + static size_t g_val = 5; + return g_val; +} + +size_t& getNameSizeLog() { + static size_t g_val = 5; + return g_val; +} +static std::vector >& getList() { + static std::vector > g_val; + return g_val; +} + +int32_t elog::registerInstance(const std::string& _name) { + for (size_t iii = 0; iii < getList().size(); ++iii) { + if (getList()[iii].first == _name) { + return iii; + } + } + getList().push_back(std::make_pair(_name, getDefaultLevel())); + if (_name.size() >= getNameSizeLog()) { + getNameSizeLog() = _name.size()+1; + } + //std::cout << "register log : '" << _name << "'=" << getList().size()-1 << std::endl; + return getList().size()-1; +} + +void elog::setLevel(const std::string& _name, enum level _level) { + for (size_t iii = 0; iii < getList().size(); ++iii) { + if (getList()[iii].first == _name) { + getList()[iii].second = _level; + return; + } + } + getList().push_back(std::make_pair(_name, _level)); +} + +void elog::setLevel(enum level _level) { + getDefaultLevel() = _level; + for (size_t iii = 0; iii < getList().size(); ++iii) { + getList()[iii].second = _level; + } +} + +void elog::setLevel(int32_t _id, enum level _level) { + if (_id < 0 || _id > (int32_t)getList().size()) { + // ERROR... + return; + } + getList()[_id].second = _level; +} + + +int32_t elog::getLevel(int32_t _id) { + if (_id < 0 || _id > (int32_t)getList().size()) { + // ERROR... + return 0; + } + return (int32_t)getList()[_id].second; +} + +std::vector elog::getListInstance() { + std::vector out; + for (size_t iii = 0; iii < getList().size(); ++iii) { + out.push_back(getList()[iii].first); + } + return out; +} + +void elog::logStream(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const std::ostream& _log) { + std::ostringstream oss; + oss << _log.rdbuf(); + std::string sss =oss.str(); + elog::logChar(_id, _level, _ligne, _className, _funcName, sss.c_str()); +} + +void elog::logChar1(int32_t _id, int32_t _level, const char* _log) { + elog::logChar(_id, _level, -1, nullptr, nullptr, _log); +} + +void elog::logStream1(int32_t _id, int32_t _level, const std::ostream& _log) { + std::ostringstream oss; + oss << _log.rdbuf(); + std::string sss =oss.str(); + elog::logChar(_id, _level, -1, nullptr, nullptr, sss.c_str()); +} + +static bool& getColor() { + static bool g_val = DEFAULT_LOG_COLOR; + return g_val; +} + +void elog::setColor(bool _status) { + getColor() = _status; +} + +static bool& getTime() { + static bool g_val = DEFAULT_LOG_TIME; + return g_val; +} +void elog::setTime(bool _status) { + getTime() = _status; +} + +static bool& getLine() { + static bool g_val = DEFAULT_LOG_LINE; + return g_val; +} +void elog::setLine(bool _status) { + getLine() = _status; +} + +static bool& getThreadId() { + static bool g_val = DEFAULT_LOG_THREAD_ID; + return g_val; +} +void elog::setThreadId(bool _status) { + getThreadId() = _status; +} + +static bool& getThreadNameEnable() { + static bool g_val = DEFAULT_LOG_THREAD_NAME; + return g_val; +} +void elog::setThreadNameEnable(bool _status) { + getThreadNameEnable() = _status; +} + +static bool& getFunction() { + static bool g_val = DEFAULT_LOG_CLASS; + return g_val; +} +void elog::setFunction(bool _status) { + getFunction() = _status; +} + +static bool& getLibName() { + static bool g_val = DEFAULT_LOG_LIB_NAME; + return g_val; +} +void elog::setLibName(bool _status) { + getLibName() = _status; +} + +static void getDisplayTime(char* data) { +#ifdef __TARGET_OS__Android + struct timeval now; + gettimeofday(&now, nullptr); + sprintf(data, " %2dh%2d'%2d ", (int32_t)(now.tv_sec/3600)%24, (int32_t)(now.tv_sec/60)%60, (int32_t)(now.tv_sec%60)); +#else + time_t rawtime; + struct tm * timeinfo; + time(&rawtime); + timeinfo = localtime(&rawtime); + sprintf(data, " %2dh%2d'%2d ", (timeinfo->tm_hour)%24, timeinfo->tm_min, timeinfo->tm_sec); +#endif +} + +//regular colors +#define ETK_BASH_COLOR_BLACK "\e[0;30m" +#define ETK_BASH_COLOR_RED "\e[0;31m" +#define ETK_BASH_COLOR_GREEN "\e[0;32m" +#define ETK_BASH_COLOR_YELLOW "\e[0;33m" +#define ETK_BASH_COLOR_BLUE "\e[0;34m" +#define ETK_BASH_COLOR_MAGENTA "\e[0;35m" +#define ETK_BASH_COLOR_CYAN "\e[0;36m" +#define ETK_BASH_COLOR_WHITE "\e[0;37m" +//emphasized (bolded) colors +#define ETK_BASH_COLOR_BOLD_BLACK "\e[1;30m" +#define ETK_BASH_COLOR_BOLD_RED "\e[1;31m" +#define ETK_BASH_COLOR_BOLD_GREEN "\e[1;32m" +#define ETK_BASH_COLOR_BOLD_YELLOW "\e[1;33m" +#define ETK_BASH_COLOR_BOLD_BLUE "\e[1;34m" +#define ETK_BASH_COLOR_BOLD_MAGENTA "\e[1;35m" +#define ETK_BASH_COLOR_BOLD_CYAN "\e[1;36m" +#define ETK_BASH_COLOR_BOLD_WHITE "\e[1;37m" +//background colors +#define ETK_BASH_COLOR_BG_BLACK "\e[40m" +#define ETK_BASH_COLOR_BG_RED "\e[41m" +#define ETK_BASH_COLOR_BG_GREEN "\e[42m" +#define ETK_BASH_COLOR_BG_YELLOW "\e[43m" +#define ETK_BASH_COLOR_BG_BLUE "\e[44m" +#define ETK_BASH_COLOR_BG_MAGENTA "\e[45m" +#define ETK_BASH_COLOR_BG_CYAN "\e[46m" +#define ETK_BASH_COLOR_BG_WHITE "\e[47m" +// Return to the normal color setings +#define ETK_BASH_COLOR_NORMAL "\e[0m" +//go to the Top of bash +#define ETK_BASH_GO_TOP "\e[0;0f" + +#define LENGHT_MAX_LOG (2048) + +void elog::logChar(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const char* _log) { + static std::mutex g_lock; + char handle[LENGHT_MAX_LOG] = ""; + memset(handle, ' ', LENGHT_MAX_LOG); + handle[0] = '\0'; + char* pointer = handle; + if(getColor() == true) { + switch(_level) { + default: + // nothing to do ... + break; + case logLevelCritical: + strcat(pointer, ETK_BASH_COLOR_BOLD_RED); + break; + case logLevelError: + strcat(pointer, ETK_BASH_COLOR_RED); + break; + case logLevelWarning: + strcat(pointer, ETK_BASH_COLOR_MAGENTA); + break; + case logLevelInfo: + strcat(pointer, ETK_BASH_COLOR_CYAN); + break; + case logLevelDebug: + strcat(pointer, ETK_BASH_COLOR_YELLOW); + break; + case logLevelVerbose: + strcat(pointer, ETK_BASH_COLOR_WHITE); + break; + case logLevelPrint: + strcat(pointer, ETK_BASH_COLOR_WHITE); + break; + } + pointer = handle+strlen(handle); + } + if(getTime() == true) { + getDisplayTime(pointer); + pointer = handle+strlen(handle); + } + #ifndef __TARGET_OS__Android + switch(_level) { + default: + strcat(pointer, "[?] "); + break; + case logLevelPrint: + strcat(pointer, "[P] "); + break; + case logLevelCritical: + strcat(pointer, "[C] "); + break; + case logLevelError: + strcat(pointer, "[E] "); + break; + case logLevelWarning: + strcat(pointer, "[W] "); + break; + case logLevelInfo: + strcat(pointer, "[I] "); + break; + case logLevelDebug: + strcat(pointer, "[D] "); + break; + case logLevelVerbose: + strcat(pointer, "[V] "); + break; + } + pointer = handle+strlen(handle); + #endif + if (getLibName() == true) { + if (_id >= 0) { + int32_t len = strlen(handle); + strcat(pointer, getList()[_id].first.c_str()); + pointer = handle+strlen(handle); + while (strlen(handle) - len < getNameSizeLog()) { + *pointer++ = ' '; + *pointer = '\0'; + } + *pointer++ = '|'; + *pointer++ = ' '; + *pointer = '\0'; + } + } + #ifdef ELOG_BUILD_ETHREAD + if(getThreadId() == true) { + // display thread ID + uint32_t iddd = ethread::getId(); + sprintf(pointer, "%3d", iddd); + pointer = handle+strlen(handle); + *pointer++ = ' '; + *pointer++ = '|'; + *pointer++ = ' '; + *pointer = '\0'; + } + if(getThreadNameEnable() == true) { + // display thread ID + std::string name = ethread::getName(); + if (name.size() >= getThreadSizeLog() ) { + getThreadSizeLog() = name.size() + 1; + } + sprintf(pointer, "%s", name.c_str()); + pointer = handle+strlen(handle); + size_t nbSpaceToAdd = getThreadSizeLog()-name.size(); + for (size_t iii=0; iii= 0) { + sprintf(pointer, "(l=%5d)", _ligne); + pointer = handle+strlen(handle); + *pointer++ = ' '; + *pointer = '\0'; + } + } + // TODO :Maybe optimize this one ... + if(getFunction() == true) { + int32_t len = strlen(handle); + char tmpName[1024]; + char *tmpPointer = tmpName; + #ifndef __TARGET_OS__Android + if (_className != nullptr) { + snprintf(tmpPointer, 1024, "%s::", _className); + tmpPointer = tmpPointer+strlen(tmpPointer); + } + #endif + if (_funcName != nullptr) { + #if defined(__TARGET_OS__Android) + // cleen for android : + char* startPos = strchr(_funcName, ' '); + char* stopPos = strchr(_funcName, '('); + if (startPos != nullptr) { + if (stopPos != nullptr) { + if(stopPos < startPos) { + snprintf(tmpPointer, std::min(1024, int32_t(stopPos-_funcName)), "%s", _funcName); + } else { + snprintf(tmpPointer, std::min(1024, int32_t(stopPos-startPos)), "%s", startPos+1); + } + } else { + snprintf(tmpPointer, 1024, "%s", startPos); + } + } else { + if (stopPos != nullptr) { + snprintf(tmpPointer, std::min(1024, int32_t(stopPos-_funcName)), "%s", _funcName); + } else { + snprintf(tmpPointer, 1024, "%s", _funcName); + } + } + #else + snprintf(tmpPointer, 1024, "%s", _funcName); + #endif + tmpPointer = tmpPointer+strlen(tmpPointer); + } + size_t lenFunc = strlen(tmpName); + if (lenFunc >= getFunctionSizeLog()) { + getFunctionSizeLog() = lenFunc+1; + } + size_t nbSpaceToAdd = getFunctionSizeLog() - lenFunc; + for (size_t iii=0; iii LENGHT_MAX_LOG - strlen(handle)-20) { + memcpy(pointer, _log, LENGHT_MAX_LOG - strlen(handle)-21); + handle[1024-25] = ' '; + handle[1024-24] = '.'; + handle[1024-23] = '.'; + handle[1024-22] = '.'; + handle[1024-21] = '\0'; + } else { + strcat(pointer, _log); + } + pointer = handle+strlen(handle); + if(getColor() == true) { + strcat(pointer, ETK_BASH_COLOR_NORMAL); + } + + g_lock.lock(); + #if defined(__TARGET_OS__Android) + // TODO : Set package name instead of ewol ... + switch(_level) { + default: + __android_log_print(ANDROID_LOG_VERBOSE, "EWOL", "%s", handle); + break; + case logLevelPrint: + __android_log_print(ANDROID_LOG_INFO, "EWOL", "%s", handle); + break; + case logLevelCritical: + __android_log_print(ANDROID_LOG_FATAL, "EWOL", "%s", handle); + break; + case logLevelError: + __android_log_print(ANDROID_LOG_ERROR, "EWOL", "%s", handle); + break; + case logLevelWarning: + __android_log_print(ANDROID_LOG_WARN, "EWOL", "%s", handle); + break; + case logLevelInfo: + __android_log_print(ANDROID_LOG_INFO, "EWOL", "%s", handle); + break; + case logLevelDebug: + __android_log_print(ANDROID_LOG_DEBUG, "EWOL", "%s", handle); + break; + case logLevelVerbose: + __android_log_print(ANDROID_LOG_VERBOSE, "EWOL", "%s", handle); + break; + } + #elif defined(__TARGET_OS__IOs) + iosNSLog(handle); + #else + std::cout << handle << std::endl; + #endif + g_lock.unlock(); + if (_level == logLevelCritical) { + std::this_thread::sleep_for(std::chrono::milliseconds(700)); + displayBacktrace(true, 2); + } +} + + diff --git a/elog/log.h b/elog/log.h new file mode 100644 index 0000000..95ce2c1 --- /dev/null +++ b/elog/log.h @@ -0,0 +1,130 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include +#include +#include + +namespace elog { + /** + * @brief Log level is a simple list of all log availlable. This enum is used when setting a log and when user chose the level of log displayed. + */ + enum level { + logLevelPrint = -1, //!< basic print for Help or result (never filtered) + logLevelNone = 0, //!< no display requested + logLevelCritical = 1, //!< Display only critical logs (note that critical generally assert with a backtrace (when we can)) + logLevelError = 2, //!< Display Error and critical logs + logLevelWarning = 3, //!< Display log critical to warning + logLevelInfo = 4, //!< Display log critical to information (removed in release mode) + logLevelDebug = 5, //!< Display log critical to debug (removed in release mode) + logLevelVerbose = 6 //!< Display all logs (removed in release and debug mode) + }; + /** + * @brief Register an element in the log system + * @param[in] _name Name of the module + * @return reference Id of an instance name + */ + int32_t registerInstance(const std::string& _name); + /** + * @brief Set the log level of a specific instance + * @param[in] _name Name of the intance + * @param[in] _id Id of the intance + * @param[in] _level New level to set on the instance + */ + void setLevel(const std::string& _name, enum level _level); + //! @previous + void setLevel(int32_t _id, enum level _level); + /** + * @brief Set global debug level + * @param[in] _level New level to set on the instance + */ + void setLevel(enum level _level); + /** + * @brief Get the current level of debug for a specific intance + * @param[in] _id Id Of the intance + * @return the enum casted in an integer ==> generise the API (not dependent of etk) + */ + int32_t getLevel(int32_t _id); + /** + * @brief Get list of all intance + * @return the name list of all intance + */ + std::vector getListInstance(); + /** + * @brief Set Color enable or disable. + * @param[in] _status New value of color. + */ + void setColor(bool _status); + /** + * @brief Set Time display enable or disable. + * @param[in] _status New value. + */ + void setTime(bool _status); + /** + * @brief Set Line display enable or disable. + * @param[in] _status New value. + */ + void setLine(bool _status); + /** + * @brief Set Function display enable or disable. + * @param[in] _status New value. + */ + void setFunction(bool _status); + /** + * @brief Set thread id enable or disable. + * @param[in] _status New value. + */ + void setThreadId(bool _status); + /** + * @brief Set thread name enable or disable. + * @param[in] _status New value. + */ + void setThreadNameEnable(bool _status); + /** + * @brief Set library display enable or disable. + * @param[in] _status New value. + */ + void setLibName(bool _status); + /** + * @brief Call log to display + * @param[in] _id Id of the instance type + * @param[in] _level Level debug + * @param[in] _ligne Line of the debug + * @param[in] _className Class name of the debug + * @param[in] _funcName Function name for debug + * @param[in] _log Stream to log + */ + void logChar(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const char* _log); + //! @previous + void logStream(int32_t _id, int32_t _level, int32_t _ligne, const char* _className, const char* _funcName, const std::ostream& _log); + //! @previous + void logChar1(int32_t _id, int32_t _level, const char* _log); + //! @previous + void logStream1(int32_t _id, int32_t _level, const std::ostream& _log); + /** + * @brief Display the current backtrace + * @param[in] _breakAtEnd assert program when backtrace is printed + */ + void displayBacktrace(bool _breakAtEnd = false, int32_t _removeElement=0); +}; +#ifdef __class__ + #undef __class__ +#endif +#define __class__ (nullptr) + +// generic define for all logs:: +#define ELOG_BASE(logId,info,data) \ + do { \ + if (info <= elog::getLevel(logId)) { \ + std::stringbuf sb; \ + std::ostream tmpStream(&sb); \ + tmpStream << data; \ + elog::logStream(logId, info, __LINE__, __class__, __func__, tmpStream); \ + } \ + } while(0) diff --git a/elog/logIOs.h b/elog/logIOs.h new file mode 100644 index 0000000..d5ee377 --- /dev/null +++ b/elog/logIOs.h @@ -0,0 +1,20 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __TARGET_OS__IOs + void iosNSLog(const char * _value); +#endif +#ifdef __cplusplus +} +#endif + + diff --git a/elog/logIOs.m b/elog/logIOs.m new file mode 100644 index 0000000..51bda87 --- /dev/null +++ b/elog/logIOs.m @@ -0,0 +1,17 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + + +#import +#include + +void iosNSLog(const char * _value) { + NSLog(@"\r%s", _value); +} + + diff --git a/lutin_elog.py b/lutin_elog.py new file mode 100644 index 0000000..2879935 --- /dev/null +++ b/lutin_elog.py @@ -0,0 +1,73 @@ +#!/usr/bin/python +import lutin.module as module +import lutin.tools as tools + + +def get_type(): + return "LIBRARY" + +def get_desc(): + return "Ewol log basic interface" + +def get_licence(): + return "APACHE-2" + +def get_compagny_type(): + return "com" + +def get_compagny_name(): + return "atria-soft" + +def get_maintainer(): + return ["Mr DUPIN Edouard "] + +def get_version(): + return [0,1,"dev"] + +def create(target, module_name): + my_module = module.Module(__file__, module_name, get_type()) + my_module.add_extra_compile_flags() + # add the file to compile: + my_module.add_src_file([ + 'elog/debug.cpp', + 'elog/log.cpp' + ]) + + if target.name=="IOs": + my_module.add_src_file('etk/logIOs.m') + + my_module.add_header_file([ + 'elog/log.h', + ]) + + if target.config["mode"] == "debug": + # Bor backtrace display : + if target.name != "Windows" \ + and target.name != "MacOs" \ + and target.name != "IOs": + # TODO : check if it is really needed ... + my_module.add_export_flag('link', [ + '-ldl', + '-rdynamic']) + elif target.name != "Windows": + my_module.add_export_flag('link', [ + '-ldl']) + # build in C++ mode + my_module.compile_version("c++", 2011) + # add dependency of the generic C++ library: + my_module.add_module_depend('cxx') + my_module.add_optionnal_module_depend('ethread', ["c++", "-DELOG_BUILD_ETHREAD"]) + + if target.name=="Windows": + pass + elif target.name=="Android": + my_module.add_module_depend("SDK") + pass + else: + #TODO : Set it in a generic include system + my_module.add_export_flag('link-lib', "pthread") + + my_module.add_path(tools.get_current_path(__file__)) + return my_module + +