I have a problem with my static libraries. I got one for the use of multimedia elements and another for C general use (linked list...). I want them to be separated to not bloat my program.
Try as I might to use functions from the second library in the first I keep getting the pesky undefined references. I can't find the answer on Google or in the gcc documentation so I came here to find the answer I seek.
How do I link together two .a files? Can gcc even do this ?
linking the .c file of an element of lib1
gcc -g3 -Wall -Wextra -Werror -I src/inc -I src/lib/*/src/inc -L src/lib -locl -o obj/menu/button.o -c src/menu/button.c
creating lib1
ar rcso ../libocml.a obj/sound/sound.o obj/sys/view.o obj/sys/window.o obj/sys/thread.o obj/sys/clock.o obj/menu/text.o obj/menu/button.o
Compiling of the binary
gcc -g3 -Wall -Wextra -I src/inc -I src/lib/*/src/inc -I src/lib/*/src/lib/*/src/inc -L src/lib -o bin/runner.exe obj/main.o -locml -lcsfml-graphics -lcsfml-window -lcsfml-audio -lcsfml-system
Unedited error
gcc -g3 -Wall -Wextra -I src/inc -I src/lib/*/src/inc -I src/lib/*/src/lib/*/src/inc -L src/lib -o bin/runner.exe obj/main.o -locml -lcsfml-graphics -lcsfml-window -lcsfml-audio -lcsfml-system
/usr/bin/ld : src/lib/libocml.a(sound.o) : dans la fonction « setMusic » :
/home/ornsolot/Bureau/runner/src/lib/ocml/src/sound/sound.c:69 : référence indéfinie vers « setStr »
/usr/bin/ld : src/lib/libocml.a(sound.o) : dans la fonction « unsetMusic » :
/home/ornsolot/Bureau/runner/src/lib/ocml/src/sound/sound.c:82 : référence indéfinie vers « unsetStr »
collect2: error: ld returned 1 exit status
make: *** [Makefile:86 : runner] Erreur 1
the issue is that setMusic and unsetMusic in music.c in lib ocml need setStr and unsetStr in str.c in lib ocl.
Source Tree Source tree
How to reproduce
you need the csfml library for compile it, sudo apt-get install libcsfml-dev
create all file at the same place where you fill use the following command.
ocml.h
#include <SFML/Graphics.h>
#include <SFML/Audio.h>
#include <stdio.h>
#define MALLOCSTR(length) (malloc(sizeof(char) * length))
typedef struct osString_s {
char *data;
size_t length;
} String_t;
String_t *setStr(char *data);
void unsetStr(String_t *string);
typedef struct ocmlMusic_s {
sfMusic *core;
String_t *name;
} Music_t;
Music_t *setMusic(char *path, sfBool loop);
void unsetMusic(Music_t *music);
str.c
#include "ocml.h"
static size_t strLen(char *string)
{
size_t len = 0;
if (string)
while (string[len] != '\0')
len++;
return (len);
}
String_t *setStr(char *data)
{
size_t len = strLen(data);
String_t *str = len > 0 ? malloc(sizeof(String_t)) : NULL;
if (str) {
str->data = MALLOCSTR(len);
for (size_t i = 0; i < len ; i++)
str->data[i] = data[i];
str->length = len;
}
return (str);
}
void unsetStr(String_t *string)
{
if (string) {
if (string->data)
free(string->data);
free(string);
}
}
gcc -g3 -Wall -Wextra -Werror -I . -o str.o -c str.c
ar rcso libocml.a str.o
music.c
#include "ocml.h"
Music_t *setMusic(char *path, sfBool loop)
{
Music_t *music = (path) ? malloc(sizeof(Music_t)) : NULL;
if (music) {
music->core = sfMusic_createFromFile(path);
sfMusic_setLoop(music->core, loop);
music->name = setStr(path);
}
return (music);
}
void unsetMusic(Music_t *music)
{
if (music) {
sfMusic_destroy(music->core);
unsetStr(music->name);
free(music);
}
}
gcc -g3 -Wall -Wextra -Werror -I . -L . -locl -o music.o -c music.c
ar rcso libocml.a music.o libocl.a
main.c
#include "ocml.h"
int main()
{
Music_t*loop = setMusic("path/to/file.ogg", sfTrue);
unsetMusic(loop);
}
gcc -g3 -Wall -Wextra -I . -L . -o a.out main.o -locml -lcsfml-graphics -lcsfml-window -lcsfml-audio -lcsfml-system
Thanks in advance for your guidance.
ar
. It looks optiona
orb
can be used to add files.libocml.a
in a different folder than you include with a -L though it isn't clear.