Undefined symbol _main, however I do have a main function? - c

Here is my console output:
Tylers-MacBook-Pro:laser_finder_c tylerjw$ make
gcc -g -Wall -c -o dots_img.o dots_img.c
gcc -g -Wall -c -o no_dots_img.o no_dots_img.c
gcc -g -Wall -c -o point.o point.c
gcc -g -Wall -c -o images.o images.c
gcc -g -Wall -c -o laser_finder_c.o laser_finder_c.c
gcc dots_img.o no_dots_img.o point.o images.o laser_finder_c.o -g -Wall -o laser_finder_c
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [laser_finder_c] Error 1
This doesn't seem to make any sense as the main function is defined in laser_finder_c.c. Below is my makefile. I'm real confused as to why this is happening.
TARGET = laser_finder_c
OBJECTS = dots_img.o no_dots_img.o point.o images.o laser_finder_c.o
#######################################################################################
CFLAGS = -g -Wall
ASFLAGS = -Wall
LDFLAGS = -g -Wall
CC = gcc
AS = gcc
########################################################################################
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $(TARGET)
point.o: point.h
images.o: images.h
laser_finder_c.o: images.h point.h
dots_img.o: images.h
no_dots_img.o: images.h
clean:
rm -f $(OBJECTS) $(TARGET)
Here is the definition of main in laser_finder_c.c
// laser_finder.c - finds the location of laser points comparing two images
#include "point.h"
#include <stdio.h>
#include <stdlib.h>
// #defines ... removed
int main()
{
// ... code removed
return 0;
}
For context the output of gcc -v is:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix

Related

How to build a program with multiple files whith inter files function calls with makefile in C

I am struggling with building a program with multiple files whith inter files function calls with makefile in C. Let's say that I have a main file which call a function call_print_hello() declared in a header file fdeclar_macros.h and written in the file script1.c. The function call_print_hello() itself calls another function print_hello() also declared in fdeclar_macros.h and written in script2.c. I have also a makefile but when I run it I get the following error message:
gcc -g -Wall -c main.c
gcc -g -Wall -c script1.c
gcc -o main main.o script1.o
Undefined symbols for architecture x86_64:
"_call_print_hello", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
Here are the content of the files:
makefile:
CC = gcc
CFLAGS = -g -Wall
main: main.o script1.o
$(CC) -o main main.o script1.o
main.o: main.c fdeclar_macros.h
$(CC) $(CFLAGS) -c main.c
script2.o: script2.c fdeclar_macros.h
$(CC) $(CFLAGS) -c script2.c
script1.o: script1.c fdeclar_macros.h
$(CC) $(CFLAGS) -c script1.c
run: main
./main
clean:
$(RM) -rf justify *.dSYM *.o
main.c:
#include "fdeclar_macros.h"
int main(){
call_print_hello();
return 0;
}
fdeclar_macros.h:
#define NUMBER 3
void print_hello();
void call_print_hello();
script1.c:
#include <stdio.h>
#include "fdeclar_macros.h"
void print_hello(){
printf("hello %d\n", NUMBER);
}
script2.c:
#include "fdeclar_macros.h"
void call_print_hello(){
print_hello();
}
The make target for the main executable does not contain a dependency on script2.o and the rule to build main does not link script2.o into the main executable either.
So the linker tries to build an executable with the content of script2.o missing, but as that content is required, linking fails.
One easy fix would be to change the original rule
main: main.o script1.o
$(CC) -o main main.o script1.o
by adding script2.o:
main: main.o script1.o script2.o
$(CC) -o main main.o script1.o script2.o
I will leave finding more general rules as an exercise to the reader.
NAME = my_programm
CC = gcc
CFLAGS = -Wall -Werror -Wextra
MY_SOURCES = main.c script1.c script2.c
MY_OBJECTS = $(MY_SOURCES:.c=.o)
$(NAME): $(MY_OBJECTS)
#cc $(CFLAGS) $(MY_OBJECTS) -o $(NAME)
clean:
#rm -f $(MY_OBJECTS)
#rm -f $(NAME)
run:
./my_programm

Did a Mac update ruin my ability to use gcc?

I am trying to compile two c files into one executable. In the directory I have only three files; Makefile, main.c and myfunction.c.
Makefile:
CC = gcc
CFLAGS = -Wall -g -O0
LIBS = -lm
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
MAIN = main
all: $(MAIN)
#echo Program has been compiled
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LIBS)
clean:
$(RM) *.o *~ $(MAIN)
main.c:
#include <stdio.h>
void myfunc();
int main (int argc, char *argv[]) {
myfunc();
return 0;
}
myfunction.c:
#include <stdio.h>
void myfunc() { printf("hello world"); }
output after make:
gcc -Wall -g -O0 -c -o main.o main.c
gcc -Wall -g -O0 -c -o myfunction.o myfunction.c
gcc -Wall -g -O0 -o main main.o myfunction.o -lm
Undefined symbols for architecture x86_64:
"_myfunc", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
I had something nearly identical working in the past. I have since clean installed MacOS and updated to Big Sur. Is this the issue or have I overlooked something?
I fixed the issue. I’m not sure what part fixed it, but installed Homebrew and used it to install gcc-10. I also deleted the project and started over.
myfunc would define like file header
myfunc.h
void myfunc()
Declare in another file
myfunc.c
void myfunc() { printf("hello world"); }
Follow the following tutorial
https://developer.gnome.org/anjuta-build-tutorial/stable/build-make.html.en

Learn c the hard way ex29 compiling/linking problem

I have a github repo representing my exercise folder. Upon running make all the compiler throws error messages saying (Ubuntu):
cc -g -O2 -Wall -Wextra -Isrc -DNDEBUG -fPIC -c -o src/libex29.o src/libex29.c
src/libex29.c: In function ‘fail_on_purpose’:
src/libex29.c:36:33: warning: unused parameter ‘msg’ [-Wunused-parameter]
int fail_on_purpose(const char* msg)
^~~
ar rcs build/libex29.a src/libex29.o
ranlib build/libex29.a
cc -shared -o build/libex29.so src/libex29.o
cc -g -Wall -Wextra -Isrc test/ex29_test.c -o test/ex29_test
/tmp/cc7dbqDt.o: In function `main':
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:21: undefined reference to `dlopen'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:22: undefined reference to `dlerror'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:25: undefined reference to `dlsym'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:26: undefined reference to `dlerror'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:33: undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'test/ex29_test' failed
make: *** [test/ex29_test] Error 1
i spent quite a lot trying to figure out how to fix undefined references. dlfcn.h is included, everything seems to be ok. Am i missing something? Please help
You must add following option when linking code using dlopen(3) :
-ldl
Here is a demo for Ubuntu 18:
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
$ cat dl.c
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
void *r;
r = dlopen("", RTLD_LAZY);
if (r != NULL)
printf("r is not null \n");
return 0;
}
$ gcc -o dl -Wall -pedantic -std=c11 dl.c -ldl
$ echo $?
0
Here is a very simple Makefile(note position of -ldl) and related make commands:
$ cat Makefile
CFLAGS=-g -O2 -Wall -Wextra -Isrc -DNDEBUG $(OPTFLAGS) $(OPTLIBS)
dl.o :dl.c
$(CC) -c $< $(CFLAGS)
dl :dl.o
$(CC) -o $# $^ $(CFLAGS) -ldl
clean :
rm -f dl dl.o
$ make clean
rm -f dl dl.o
$ make dl
cc -c dl.c -g -O2 -Wall -Wextra -Isrc -DNDEBUG
dl.c: In function ‘main’:
dl.c:5:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
int main(int argc, char **argv)
^~~~
dl.c:5:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
int main(int argc, char **argv)
^~~~
cc -o dl dl.o -g -O2 -Wall -Wextra -Isrc -DNDEBUG -ldl
$ ./dl
r is not null
Usually the references you're missing can be resolved by adding linker flag -ldl.
You didn't mention which operating system you're using.
In case you're on Windows you'll need this library: https://github.com/dlfcn-win32/dlfcn-win32

Dynamic Link Library using makefile

Hello to the good people of Stack Overflow, I am back at it again with the questions! haha
So I have a couple of files that I am trying to compile and link together. The library I have created is a DLL. Using a RTLD_LAZY method. I have the library in the same directory as the application. I'm having a tough time completing this task. I'm trying to link it using -ldl.
My files that I have are:
lab3.c //Which has my main
myLibrary.c //which is my library
sdv.h //which is my header file
testDynamic.c //which is my handle file for the RTLD_LAZY
Here is what I have done so far, but I'm clearly screwing something up..
dynamic: lab3.o myLibrary.o test
gcc -o dynamic lab3.o myLibrary.o -lm
lab3.o: lab3.c
gcc -fPIC -c -o lab3.o lab3.c -lm
myLibrary.o: myLibrary.c
gcc -fPIC -c myLibrary.c -o myLibrary.o -lm
libmyLibrary.so: myLibrary.o
gcc -shared -o libmyLibrary.so myLibrary.o -lm
testDynamic.o:
gcc testDynamic.c -L. -lmyLibrary -o test -ldl
export LD_LIBRARY_PATH=./
Any advice will be greatly appreciated! Thanks in advance!
Here comes an example close to your own makefile.
makefile:
CC=gcc
CFLAGS=-Wall -Wextra -Werror -std=gnu99
.PHONY:all mrproper clean
all:libmyLibrary.so dynamic testDynamic
dynamic:lab3.o
$(CC) $(CFLAGS) -o dynamic lab3.o -L. -lmyLibrary -lm
lab3.o:lab3.c
$(CC) $(CFLAGS) -c -o lab3.o lab3.c
myLibrary.o:myLibrary.c
$(CC) $(CFLAGS) -fPIC -c myLibrary.c -o myLibrary.o
libmyLibrary.so:myLibrary.o
$(CC) $(CFLAGS) -shared -o libmyLibrary.so myLibrary.o -lm
testDynamic.o:testDynamic.c
$(CC) $(CFLAGS) -o testDynamic.o -c testDynamic.c
testDynamic:testDynamic.o
$(CC) $(CFLAGS) -o testDynamic testDynamic.o -ldl
mrproper:clean
rm -f dynamic libmyLibrary.so testDynamic
clean:
rm -f lab3.o myLibrary.o testDynamic.o
Use -lm only when linking. -fPic is only necessary when linking dynamic library. -lmyLibrary is only necessary when linking program with dynamic library. So generating testDynamic does not need it as it will load library dynamically, it does not require being linked to it.
sdv.h:
#ifndef SDV_H
#define SDV_H
extern void sdv_print_version();
#endif
myLibrary.c:
#include <stdio.h>
#include <stdlib.h>
void sdv_print_version()
{
printf("v1.0\n");
}
testDynamic.c:
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#define MY_LIB "libmyLibrary.so"
#define PRINT_VERSION "sdv_print_version"
int main()
{
void *handle = dlopen(MY_LIB, RTLD_LAZY);
if (handle == NULL)
{
fprintf(stderr, "%s\n", dlerror());
return 1;
}
void (*p_print_version)() = NULL;
p_print_version = dlsym(handle, PRINT_VERSION);
if (p_print_version == NULL)
{
printf("No version available.\n");
fprintf(stderr, "%s\n", dlerror());
}
else
{
(*p_print_version)();
}
if (dlclose(handle) != 0)
{
fprintf(stderr, "%s\n", dlerror());
}
return 0;
}
Now building:
>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm
gcc -Wall -Wextra -Werror -std=gnu99 -c -o lab3.o lab3.c
gcc -Wall -Wextra -Werror -std=gnu99 -o dynamic lab3.o -L. -lmyLibrary -lm
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic.o -c testDynamic.c
gcc -Wall -Wextra -Werror -std=gnu99 -o testDynamic testDynamic.o -ldl
Let's keep a first version of dynamic library:
>mkdir v1.0
>mv libmylibrary.so v1.0/
Now update myLibrary.c:
#include <stdio.h>
#include <stdlib.h>
void sdv_print_version()
{
printf("v2.0\n");
}
Build again:
>make
gcc -Wall -Wextra -Werror -std=gnu99 -fPIC -c myLibrary.c -o myLibrary.o
gcc -Wall -Wextra -Werror -std=gnu99 -shared -o libmyLibrary.so myLibrary.o -lm
Let's move this new dynamic library to another directory:
>mkdir v2.0
>mv libmylibrary.so v2.0/
Now testing with no dynamic library available:
>export LD_LIBRARY_PATH=./
>PATH=$PATH:.
>dynamic
dynamic: error while loading shared libraries: libmyLibrary.so: cannot open shared object file: No such file or directory
>testDynamic
libmyLibrary.so: cannot open shared object file: No such file or directory
What's the difference? In "testDynamic.c" we could, instead of showing a message error, do an alternative algorithm not requiring "libmyLibrary.so".
Now checking we can use "libmyLibrary.so":
>cd v1.0
>../dynamic
v1.0
>../testDynamic
v1.0
>cd ../v2.0
>../dynamic
v2.0
>../testDynamic
v2.0

Trying to use matlab's libmat.dll, but the compiler doesn't recognize the function from the library

I am trying to use matlab libmat.dll in a C application. To compile my C application I use MinGW, for now I use matlab exemple "matcreate.c" and try to compile it, so the projects consist of only one file : main.c .
Here is the makefile I use :
MATINCLUDE = "C:\Program Files\MATLAB\R2010a\extern\include"
MATLIBRARY = "C:\Program Files\MATLAB\R2010a\bin\win64"
#
CC = gcc
LD = gcc
CFLAGS = -O3 -Wall
LFLAGS = -Wall -O3
LIBS = -I$(MATINCLUDE) -L$(MATLIBRARY)
#
PROG = matTest
LISTEOBJ = \
main.o
.c.o :
$(CC) -c $(CFLAGS) $(LIBS) -o $# $<
all : $(PROG)
$(PROG) : $(LISTEOBJ)
$(LD) -o $(PROG) $(LFLAGS) $(LISTEOBJ) $(LIBS)
clean :
rm -f *.obj
Here is what I get in the console
E:\Users\Desk\Dropbox\matTest>make
gcc -c -O3 -Wall -I"C:\Program Files\MATLAB\R2010a\extern\include" -L"C:\Pr
ogram Files\MATLAB\R2010a\bin\win64" -o main.o main.c
gcc -o Hello_world -Wall -O3 main.o -I"C:\Program Files\MATLAB\R2010a\extern\i
nclude" -L"C:\Program Files\MATLAB\R2010a\bin\win64"
main.o:main.c:(.text.startup+0x48): undefined reference to `matOpen'
main.o:main.c:(.text.startup+0x6e): undefined reference to `mxCreateDoubleMatrix
_730'
e:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: main.o: ba
d reloc address 0x6e in section `.text.startup'
e:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link
failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
make: *** [Hello_world] Error 1
Why do I have "undefined reference to matOpen'" and "undefined reference to mxCreateDoubleMatrix" ?? those function are declared in mat.h. and I added #include "mat.h" to the begining of main.c
thank you
Looks like you have included the path to the matlab library, but not the library itself. You need to add a -l<libraryname> to your link line.

Resources