0

Issue

When compiling my project, I get an error with the log4cpp files. The error is the following : /usr/include/log4cpp/Priority.hh:49:2: erreur: #error Naming collision for 'DEBUG' detected. Please read the FAQ for a workaround.

The file

The file referenced by this error is a header installed with Log4cpp. Here it is. The errors are on lines 49, 78 and 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

Research

The only FAQ referencing this issue was I found was on log4cpp's Sourceforge. Here is what it says :

This is caused by the rudeness of some platforms, which mutilate the namespace with some blunt #defines. To be more precise, the Win32 API includes #defines of 'ERROR' and 'DEBUG'. Since the preprocessor is unaware of C++ naming scopes this results in reserving the words ERROR and DEBUG litterally everywhere. In particular this conflicts with log4cpp::Prioritiy::ERROR and log4cpp::Priority::DEBUG. These latter two names come from log4j, so they are not something we made up ourselves. They Win32 authors should not have rudelessly claimed these generic names through the preprocessor. There are much better alternatives:

If they use it as an integer constant, declare it using a language construct. Either 'enum {ERROR=1};' or 'static const int ERROR=1;'

would do fine. Use a less generic name like WIN32API_ERROR to make naming conflicts less likely In case they use it as a flag for conditional compilation, use '#define DEBUG DEBUG' and '#if defined(DEBUG)'. In that case the preprocessor would simply replace all occurrences of 'DEBUG' in the source code with 'DEBUG', in effect leaving everything intact.

Of course the proper solution would be if the offending party would use one of the above methods, but we could have to wait some time for this to actually happen. As an alternative log4cpp can workaround these #defines. The workaround code is enabled by doing #define LOG4CPP_FIX_ERROR_COLLISION 1 before #including any log4cpp header files and after #including all platform headers. For Win32 platforms this #define has already been included in log4cpp/config-win32.h.

Once log4cpp has been updated to the log4j 1.2 API we can get rid of this problem by adopting the new names for log levels.

Context

The thing is, I am not supposed to change the source code. I can only modify compilation configuration files (this project uses Apache Ant builder, build.xml files and bash scripts).

I'm quite new to this project and I can't ask the previous developper for help.

Question

Has anybody encountered this error before ? Is there any possible workaround other than changing the source codes and it's defines ? Are my environment variables the cause ?

I will continue my search, but any insight would be usefull. Thanks !

Clovel
  • 58
  • 10

1 Answers1

0

Like it says in the docs, you need to define LOG4CPP_FIX_ERROR_COLLISION. If you are not allowed to modify any source, you should be able to do it in your build.xml:

<define name="LOG4CPP_FIX_ERROR_COLLISION" value="1" />
mnistic
  • 10,866
  • 2
  • 19
  • 33
  • Hi, thanks for your quick answer. It seems that it is defined in other parts of the project, in Qt project files (.pro/.pri) and in Makefiles. I will test adding the defines in those. Will keep you posted. – Clovel Apr 23 '18 at 15:10