Thread: User-Defined Static Library Not Linking Against Program

  1. #1
    Registered User
    Join Date
    Oct 2010
    Posts
    107

    User-Defined Static Library Not Linking Against Program

    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.
    Last edited by QuadraticFighte; 10-15-2010 at 12:40 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    > gcc -L. -lprintfc main.c -o ./run2
    Try

    gcc main.c -o ./run2 -L. -lprintfc

    You need unresolved symbols from main.c to exist at the point you scan the library for those unresolved symbols.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2010
    Posts
    107
    Quote Originally Posted by Salem View Post
    > gcc -L. -lprintfc main.c -o ./run2
    Try

    gcc main.c -o ./run2 -L. -lprintfc

    You need unresolved symbols from main.c to exist at the point you scan the library for those unresolved symbols.
    Thanks, that solved my problem exactly! I didn't know that the order of specifying the library mattered that much. I learn something new every day!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ Library Program
    By the rofl waffle in forum C++ Programming
    Replies: 13
    Last Post: 04-28-2010, 03:44 AM
  2. A C++ program problem.
    By hector_ronado in forum C++ Programming
    Replies: 1
    Last Post: 11-28-2009, 09:26 AM
  3. Hi, Quiz C program Assignment updated
    By Eman in forum C Programming
    Replies: 19
    Last Post: 11-22-2009, 04:50 PM
  4. Problem with Free.
    By chakra in forum C Programming
    Replies: 9
    Last Post: 12-15-2008, 11:20 AM
  5. Linking errors with static var
    By Elysia in forum C++ Programming
    Replies: 8
    Last Post: 10-27-2007, 05:24 PM