ad
Пользователь
Сообщений: 70
|
 |
« Ответ #4 : 19 Март, 2014, 19:14:17 » |
|
Приведите, пожалуйста, точные технические данные — укажите версию QNX, сообщение об ошибке, команду компиляции и линковки. Если возможно, то вышлите целиком минимальный пример проекта, с которым данная ситуация воспроизводится.
Операционная система - QNX 6.5.0. Компилятор - GCC 4.2.2. Вот полное описание ошибок: ...Projects/fpo/mztf/bulat.ya1/kc-logger # make make -j 1 -Cx86 -fMakefile make[1]: Entering directory `/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86' make -j 1 -Co -fMakefile make[2]: Entering directory `/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86/o' /usr/qnx650/host/qnx6/x86/usr/bin/qcc -Vgcc_ntox86 -c -Wc,-Wall -O -O3 -DNDEBUG -I. -I/home/ad/Projects/fp o/mztf/bulat.ya1/kc-logger/x86/o -I/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86 -I/home/ad/Projects/fpo/mztf/bu lat.ya1/kc-logger -I/usr/qnx650/target/qnx6/usr/include -DBUILDENV_qss /home/ad/Projects/fpo/mztf/bulat.ya1/kc-l ogger/bit_operations.cpp /usr/qnx650/host/qnx6/x86/usr/bin/qcc -Vgcc_ntox86 -c -Wc,-Wall -O -O3 -DNDEBUG -I. -I/home/ad/Projects/fp o/mztf/bulat.ya1/kc-logger/x86/o -I/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86 -I/home/ad/Projects/fpo/mztf/bu lat.ya1/kc-logger -I/usr/qnx650/target/qnx6/usr/include -DBUILDENV_qss /home/ad/Projects/fpo/mztf/bulat.ya1/kc-l ogger/config_reader.cpp /usr/qnx650/host/qnx6/x86/usr/bin/qcc -Vgcc_ntox86 -c -Wc,-Wall -O -O3 -DNDEBUG -I. -I/home/ad/Projects/fp o/mztf/bulat.ya1/kc-logger/x86/o -I/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86 -I/home/ad/Projects/fpo/mztf/bu lat.ya1/kc-logger -I/usr/qnx650/target/qnx6/usr/include -DBUILDENV_qss /home/ad/Projects/fpo/mztf/bulat.ya1/kc-l ogger/main.cpp /usr/qnx650/host/qnx6/x86/usr/bin/qcc -Vgcc_ntox86 -c -Wc,-Wall -O -O3 -DNDEBUG -I. -I/home/ad/Projects/fp o/mztf/bulat.ya1/kc-logger/x86/o -I/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86 -I/home/ad/Projects/fpo/mztf/bu lat.ya1/kc-logger -I/usr/qnx650/target/qnx6/usr/include -DBUILDENV_qss /home/ad/Projects/fpo/mztf/bulat.ya1/kc-l ogger/str_functions.cpp /bin/rm -f /home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86/o/kc-logger /usr/qnx650/host/qnx6/x86/usr/bin/qcc -Vgcc_ntox86 -lang-c++ -lang-c++ -Wl,-S -o/home/ad/Projects/fpo/mztf/bulat.y a1/kc-logger/x86/o/kc-logger bit_operations.o config_reader.o main.o str_functions.o -L . -L /home/ad/P rojects/fpo/mztf/bulat.ya1/kc-logger/Libraries/x86/a -L /usr/qnx650/target/qnx6/x86/lib -L /usr/qnx650/target/qnx6/x8 6/usr/lib -Wl,--rpath-link . -Wl,--rpath-link /home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/Libraries/x86/a -Wl,--r path-link /usr/qnx650/target/qnx6/x86/lib -Wl,--rpath-link /usr/qnx650/target/qnx6/x86/usr/lib -Bstatic -llogge r -lpulsar_socket -lpulsar -Bdynamic -lmenu -lpanel -lncurses -lsocket main.o: In function `main': main.cpp:(.text+0x31): undefined reference to `lmsg_init(char const*, LoggerLevel, unsigned int, unsigned int, char*) ' main.cpp:(.text+0x91): undefined reference to `lmsg_log(LoggerLevel, unsigned int, char const*, ...)' main.cpp:(.text+0xad): undefined reference to `lmsg_log(LoggerLevel, unsigned int, char const*, ...)' main.cpp:(.text+0xb2): undefined reference to `lmsg_close()' cc: /usr/qnx650/host/qnx6/x86/usr/bin/ntox86-ld error 1 make[2]: *** [/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86/o/kc-logger] Error 1 make[2]: Leaving directory `/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86/o' make[1]: *** [all] Error 2 make[1]: Leaving directory `/home/ad/Projects/fpo/mztf/bulat.ya1/kc-logger/x86' make: *** [all] Error 2 Вот код библиотеки. Header: /** logger.h * This file describes the log-functions and variables **/
#ifndef LOGGER_H_05550 #define LOGGER_H_05550
#include <syslog.h> #include <sys/types.h> #include <stdarg.h> #include <stdio.h> #include <stdint.h>
#ifdef __cplusplus extern "C" { #endif
#define MAX_APP_NAME_LEN 1024
typedef uint32_t LoggerVerbosityLevel; ///< in debug each loop level should increment it
typedef enum { LogEmerg = 0, LogAlert, LogCrit, LogErr, LogWarning, LogNotice, LogInfo, LogDebug } LoggerLevel;
#define LOG_OUTPUT_NONE 0 #define LOG_OUTPUT_SYSLOG 1 #define LOG_OUTPUT_TTY 2 /// 3, 7, 15, 31 and etc is not defined, because in binary mode they are consist from units #define LOG_OUTPUT_FILE 4
#define LOGGER_OUTPUT_MASK 0x7
/// Structure of the log message typedef struct { LoggerLevel level; ///< log level of the message char* header; ///< header of the message char* text; ///< text of the message FILE* file; ///< possibility of writing to file } LMessage;
/** * @brief Initialization the logger * @param app_name - name of the application * @param log_level - level of the log message * @param verbosity - type of the log verbosity * @param dev - output device (tty, or file, or syslog) * @param file_name - name of the file (if the file is exist) **/ void lmsg_init(const char* app_name, LoggerLevel log_level, LoggerVerbosityLevel verbosity, uint32_t dev, char* file_name);
/** * @brief Prints the message to an output device * @param log_level - level of the log message * @param verbosity - type of the log verbosity * @param message - outputing message **/ void lmsg_log(LoggerLevel log_level, LoggerVerbosityLevel verbosity, const char* message, ...);
/** @brief Closes the logger output and free memory **/ void lmsg_close();
#ifdef __cplusplus }; #endif
#endif //LOGGER_H_05550
Realization: #include "logger.h"
#include <string.h> #include <time.h> #include <pthread.h> #include <stdlib.h>
/// @name Declaration /**@{*/
/// @name Global variables /**@{*/
static struct timespec last_time = {}; ///< time of the log writing static char* application_name = NULL; ///< name of the application static LoggerLevel init_level; ///< level of the messages static LoggerVerbosityLevel init_verb; ///< verbosity of the messages static char* init_fname = NULL; ///< file name of the output file static FILE* log_file = NULL; ///< log-file
static uint32_t output_flags = 0; ///< flags which determine the output typedef void(*out_method)(LMessage* message); ///< callback for the output method static out_method* output_methods = NULL; ///< pointer to the current output method
static pthread_mutex_t log_lock; /// mutex which locks for writing
/**@}*/
/// @name Global functions /**@{*/
static void to_syslog(LMessage* message); ///< print the message to syslog static void to_tty(LMessage* message); ///< print the message to screen static void to_file(LMessage* message); ///< print the message to file
static char* getHeader(LoggerLevel log_level); ///< get the header of the each message
static const int level2syslog(LoggerLevel log_level); ///< translation the level to syslog type static const char* level2str(LoggerLevel log_level); ///< translation the level to string
/**@}*/ /**@}*/
/// @name Realization /**@{*/
/// Initialization the logger void lmsg_init(const char* app_name, LoggerLevel log_level, LoggerVerbosityLevel verbosity, uint32_t dev, char* file_name) { init_level = log_level; init_verb = verbosity; output_flags = (dev & LOGGER_OUTPUT_MASK); init_fname = file_name;
pthread_mutex_init(&log_lock, NULL);
const char default_app_name[] = "unknown application";
int sl = strlen(app_name); if(sl > MAX_APP_NAME_LEN - 1) sl = MAX_APP_NAME_LEN - 1; if(!sl) { sl = strlen(default_app_name); app_name = default_app_name; }
application_name = malloc(sl); strcpy(application_name, app_name);
if(init_fname) log_file = fopen(init_fname, "a"); uint32_t tmp_m = output_flags; int c = 0; while(tmp_m) { if(tmp_m & 0x1) ++c; tmp_m = (tmp_m >> 1); }
output_methods = (out_method*)malloc(c + 1);
output_methods[c] = NULL; c = 0; if(output_flags & LOG_OUTPUT_SYSLOG) { openlog(application_name, 0, LOG_DAEMON); output_methods[c] = &to_syslog; ++c; } if(output_flags & LOG_OUTPUT_TTY) { output_methods[c] = &to_tty; ++c; } if(output_flags & LOG_OUTPUT_FILE) { output_methods[c] = &to_file; ++c; } }
/// Print the message to an output device void lmsg_log(LoggerLevel log_level, LoggerVerbosityLevel verbosity, const char* message, ...) { if(init_level < log_level || init_verb < verbosity) return;
static char buffer[4 * MAX_APP_NAME_LEN] = {}; static LMessage msg_struct;
pthread_mutex_lock(&log_lock);
va_list args; va_start(args, message); vsprintf(buffer, message, args); va_end(args);
msg_struct.level = log_level; msg_struct.header = getHeader(log_level); msg_struct.text = buffer; msg_struct.file = log_file;
int i = -111111; for(i=0; output_methods[i]; ++i) output_methods[i](&msg_struct);
pthread_mutex_unlock(&log_lock); }
/// Print the message to syslog static void to_syslog(LMessage* message) { syslog(level2syslog(message -> level), "%s", message -> text); }
/// Print the message to screen static void to_tty(LMessage* message) { printf("%s %s\n", message -> header, message -> text); fflush(stdout); }
/// Print the message to file static void to_file(LMessage* message) { FILE* thf = message -> file; if(!thf) return;
fputs(message -> header, thf); fputs(message -> text, thf); fputs("\n", thf); fflush(thf); }
/// Get the header of the each message static char* getHeader(LoggerLevel log_level) { static char header_str[MAX_APP_NAME_LEN]; static struct timespec rawtime = {}; static struct tm* timeinfo = NULL;
memset(header_str, 0, MAX_APP_NAME_LEN); if(clock_gettime(CLOCK_REALTIME, &rawtime) != -1) { timeinfo = localtime(&rawtime.tv_sec); static char tmp_t[21] = {}, tmp_t1[11] = {}; if((!timeinfo -> tm_hour && !timeinfo -> tm_min && !timeinfo -> tm_sec) || (!last_time.tv_sec && !last_time.tv_nsec)) { strftime(tmp_t, sizeof(tmp_t), "%d.%m.%Y %A", timeinfo); strftime(tmp_t1, sizeof(tmp_t1), "%T", timeinfo); sprintf(header_str, "%s %s\n%s%s: ", tmp_t, application_name, level2str(log_level), tmp_t1); } else { strftime(tmp_t, sizeof(tmp_t), "%T", timeinfo); sprintf(header_str, "%s%s: ", level2str(log_level), tmp_t); } last_time = rawtime; }
return header_str; }
/// Translation the level to syslog type static const int level2syslog(LoggerLevel log_level) { static const int translation[] = { LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG }; return translation[log_level]; }
/// Translation the level to string static const char* level2str(LoggerLevel log_level) { static const char* translation[] = { "EMERG ", "ALERT ", "CRIT ", "ERROR ", "WARNING ", "NOTICE ", "INFO ", "DEBUG " }; return translation[log_level]; }
/// Close the logger output and free memory void lmsg_close() { if(log_file) fclose(log_file);
if(output_flags & LOG_OUTPUT_SYSLOG) closelog();
if(output_methods) free(output_methods);
free(application_name); }
/**@}*/
|