Hi, I am trying to create a static library for a small function I wrote called printfc which acts like printf except that it accepts additional arguments for color attributes. It is intended to work only on a bash console or any console that honors the particular escape codes I am using. I can compile and run it just fine when I compile printf.c into printfc.o and link it with my program. The problem comes in when I try to statically link libprintfc.a with my program, I get the dreaded "undefined reference to printfc." At the top, if it matters, I am using gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
Here's printfc.h
Code:
#ifndef PRINTFC_H
#define PRINTFC_H
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define TEXT_NORMAL 0
#define TEXT_BOLD 1
#define TEXT_UNDERSCORE 4
#define TEXT_BLINKING 5 // Doesn't seem to work
#define TEXT_REVERSE_VIDEO 7
#define TEXT_CONCEALED 8
#define TEXT_FOREGROUND_BLACK 30
#define TEXT_FOREGROUND_RED 31
#define TEXT_FOREGROUND_GREEN 32
#define TEXT_FOREGROUND_YELLOW 33
#define TEXT_FOREGROUND_BLUE 34
#define TEXT_FOREGROUND_MAGENTA 35
#define TEXT_FOREGROUND_CYAN 36
#define TEXT_FOREGROUND_WHITE 37
#define TEXT_BACKGROUND_BLACK 40
#define TEXT_BACKGROUND_RED 41
#define TEXT_BACKGROUND_GREEN 42
#define TEXT_BACKGROUND_YELLOW 43
#define TEXT_BACKGROUND_BLUE 44
#define TEXT_BACKGROUND_MAGENTA 45
#define TEXT_BACKGROUND_CYAN 46
#define TEXT_BACKGROUND_WHITE 47
void printfc(int style, int fcolor, int bcolor, const char* format, ...);
char* strchr_many(const char*, const char*);
char* strrchr_many(const char*, const char*);
#endif
Here's printfc.c
Code:
#include "printfc.h"
// Prints out a formatted string subject to the text attributes passed.
// New lines, tabs, vertical tabs, and form feeds will not be colored.
//
// NOTE: Format arguments passed are not subject to this rule. That means
// it's possible to pass a string containing such white space as new lines
// tabs, vertical tabs or form feeds, but those will be improperly colored.
void printfc(int style, int fcolor, int bcolor, const char* format, ...)
{
char* _format = strdup(format);
char* _begin = _format;
char* _end = _format + strlen(_format) - 1;
char* _line = strchr_many(_begin, "\n\f\t\v");
char t;
va_list args;
va_start(args, format);
while(_begin < _end && _begin != NULL)
{
if(_line != NULL)
{
t = *_line;
*_line = 0;
}
// Escape our color attributes
if(bcolor != 0)
printf("%c[%d;%d;%dm", 0x1B, style, fcolor, bcolor);
else
printf("%c[%d;%dm", 0x1B, style, fcolor);
// Invoke the real printf()
vprintf(_begin, args);
// End our use of color attributes
printf("%c[%dm", 0x1B, 0);
if(_line == NULL)
break;
// Actually do the new line
printf("%c", t);
// Advance to the next new line
_begin = _line + 1;
if(_begin > _end)
break;
_line = strchr_many(_begin, "\n\f\t\v");
}
va_end(args);
free(_format);
}
// Same as strchr() except it returns a pointer to the first character
// in the string that matches ANY of the characters in cs.
char* strchr_many(const char* string, const char* cs)
{
int x = strlen(string);
int y = strlen(cs);
int i, j;
for(i = 0; i < x; ++i)
for(j = 0; j < y; ++j)
if(string[i] == cs[j])
return (char*)string + i;
return NULL;
}
// Same as strrchr() except it returns a pointer to the last character
// in the string that matches ANY of the characters in cs.
char* strrchr_many(const char* string, const char* cs)
{
int x = strlen(string);
int y = strlen(cs);
int i, j;
for(i = x - 1; i >= 0; i--)
for(j = 0; j < y; ++j)
if(string[i] == cs[j])
return (char*)string + i;
return NULL;
}
Here's main.c
Code:
#include "printfc.h"
int main(int argc, char** argv)
{
printfc( TEXT_BOLD,
TEXT_FOREGROUND_BLUE,
TEXT_BACKGROUND_RED, "Hello,\n\tthere\v World!\fHow's it going?\n");
printf("Hello,\n\tthere\v World!\fHow's it going?\n");
return 0;
}
To generate the static library, I am running these commands:
Code:
gcc -c printfc.c -o printfc.o
ar rcs libprintfc.a printfc.o
My attempt to compile and link with it was met with
Code:
gcc -L. -lprintfc main.c -o ./run2
/tmp/ccBlotsy.o: In function `main':
main.c:(.text+0x29): undefined reference to `printfc'
collect2: ld returned 1 exit status
make: *** [static-link] Error 1
This makes no sense to me since
Code:
nm libprintfc.a
printfc.o:
U free
U printf
0000000000000000 T printfc
U putchar
0000000000000252 T strchr_many
U strdup
U strlen
00000000000002d8 T strrchr_many
U vprintf
I feel that I am just making a simple mistake. I would be grateful if someone would point me in the right direction.