Обнаружено столкновение имен в Log4cpp для сообщения DEBUG.
вопрос
При компиляции моего проекта я получаю сообщение об ошибке с файлами log4cpp. Ошибка заключается в следующем: /usr/include/log4cpp/Priority.hh:49:2: erreur: #error Naming collision for 'DEBUG' detected. Please read the FAQ for a workaround.
Файл
Файл, на который ссылается эта ошибка, является заголовком, установленным с Log4cpp. Вот. Ошибки в строках 49, 78 и 109
/*
* Priority.hh
*
* Copyright 2000, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
* Copyright 2000, Bastiaan Bakker. All rights reserved.
*
* See the COPYING file for the terms of usage and distribution.
*/
#ifndef _LOG4CPP_PRIORITY_HH
#define _LOG4CPP_PRIORITY_HH
#include <log4cpp/Portability.hh>
#include <string>
#include <stdexcept>
/*
* Optionally work around rudeness in windows.h on Win32.
*/
#ifdef ERROR
#ifdef LOG4CPP_FIX_ERROR_COLLISION
namespace log4cpp {
static const int _tmpERRORValue = ERROR;
}
#undef ERROR
static const int ERROR = log4cpp::_tmpERRORValue;
#define ERROR ERROR
#else // LOG4CPP_FIX_ERROR_COLLISION
#error Naming collision for 'ERROR' detected. Please read the FAQ for a \
workaround.
#endif // LOG4CPP_FIX_ERROR_COLLISION
#endif // ERROR
/*
* Other Win32 rudeness in EDK.h
*/
#ifdef DEBUG
#ifdef LOG4CPP_FIX_ERROR_COLLISION
#undef DEBUG
#define DEBUG DEBUG
#else // LOG4CPP_FIX_ERROR_COLLISION
#error Naming collision for 'DEBUG' detected. Please read the FAQ for a \
workaround.
#endif // LOG4CPP_FIX_ERROR_COLLISION
#endif // DEBUG
namespace log4cpp {
/**
* The Priority class provides importance levels with which one
* can categorize log messages.
**/
class LOG4CPP_EXPORT Priority {
public:
static const int MESSAGE_SIZE; // = 8;
/**
* Predefined Levels of Priorities. These correspond to the
* priority levels used by syslog(3).
**/
typedef enum {EMERG = 0,
FATAL = 0,
ALERT = 100,
CRIT = 200,
ERROR = 300,
WARN = 400,
NOTICE = 500,
INFO = 600,
DEBUG = 700,
NOTSET = 800
} PriorityLevel;
/**
* The type of Priority Values
**/
typedef int Value;
/**
* Returns the name of the given priority value.
* Currently, if the value is not one of the PriorityLevel values,
* the method returns the name of the largest priority smaller
* the given value.
* @param priority the numeric value of the priority.
* @returns a string representing the name of the priority.
**/
static const std::string& getPriorityName(int priority) throw();
/**
* Returns the value of the given priority name.
* This can be either one of EMERG ... NOTSET or a
* decimal string representation of the value, e.g. '700' for DEBUG.
* @param priorityName the string containing the the of the priority
* @return the value corresponding with the priority name
* @throw std::invalid_argument if the priorityName does not
* correspond with a known Priority name or a number
**/
static Value getPriorityValue(const std::string& priorityName)
throw(std::invalid_argument);
};
}
#endif // _LOG4CPP_PRIORITY_HH
Исследование
Единственный FAQ, касающийся этой проблемы, был найден в Sourceforge log4cpp. Вот что это говорит:
Это вызвано грубостью некоторых платформ, которые искажают пространство имен с помощью некоторых тупых #defines. Точнее говоря, Win32 API включает в себя #defines 'ERROR' и 'DEBUG'. Поскольку препроцессор не знает областей именования C++, это приводит к тому, что слова ERROR и DEBUG буквально зарезервированы повсюду. В частности, это конфликтует с log4cpp::Prioritiy::ERROR и log4cpp::Priority::DEBUG. Эти последние два имени происходят из log4j, поэтому они не являются тем, что мы придумали сами. Они, авторы Win32, не должны были безжалостно требовать эти общие имена через препроцессор. Есть намного лучшие альтернативы:
If they use it as an integer constant, declare it using a language construct. Either 'enum {ERROR=1};' or 'static const int ERROR=1;'
будет хорошо Используйте менее универсальное имя, такое как WIN32API_ERROR, чтобы сделать конфликты имен менее вероятными. Если они используют его как флаг для условной компиляции, используйте "#define DEBUG DEBUG" и "#iffined(DEBUG)". В этом случае препроцессор просто заменит все вхождения 'DEBUG' в исходном коде на 'DEBUG', фактически оставив все в целости и сохранности.
Конечно, правильное решение было бы, если бы сторона-нарушитель использовала один из вышеперечисленных методов, но мы могли бы подождать некоторое время, чтобы это действительно произошло. В качестве альтернативы log4cpp может обойти эти #defines. Код временного решения можно включить, выполнив #define LOG4CPP_FIX_ERROR_COLLISION 1 до #include любых заголовочных файлов log4cpp и после #include всех заголовков платформы. Для платформ Win32 этот #define уже был включен в log4cpp/config-win32.h.
После обновления log4cpp до API log4j 1.2 мы сможем избавиться от этой проблемы, приняв новые имена для уровней журналов.
контекст
Дело в том, что я не должен менять исходный код. Я могу изменять только файлы конфигурации компиляции (этот проект использует Apache Ant Builder, build.xml
файлы и скрипты bash).
Я довольно новичок в этом проекте, и я не могу попросить предыдущего разработчика о помощи.
Вопрос
Кто-нибудь сталкивался с этой ошибкой раньше? Есть ли возможный обходной путь, кроме изменения исходных кодов, и он определяет? Являются ли мои переменные среды причиной?
Я продолжу свой поиск, но любое понимание будет полезным. Спасибо!
1 ответ
Как сказано в документации, вам нужно определить LOG4CPP_FIX_ERROR_COLLISION
, Если вам не разрешено изменять какой-либо источник, вы можете сделать это в вашем build.xml:
<define name="LOG4CPP_FIX_ERROR_COLLISION" value="1" />