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
Related
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
This is the error when I run make:
Undefined symbols for architecture arm64:
"\_add", referenced from:
\_main in a4-1-989722.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: \*\*\* \[a4-1\] Error 1
note (one of the functions in my module is add()
This is the makefile:
CC = gcc
CFLAGS = -Wall -Wextra -pedantic
TARGET = a4-1
DEP1 = myMath
all: $(TARGET)
debug: CFLAGS += -DDBUG
debug: $(TARGET)
&(TARGET): $(TARGET).c $(DEP1).o
$(CC) $(CFLAGS) $(DEP1).o -o $(TARGET) $(TARGET).c
$(DEP1).o: $(DEP1).c
$(CC) $(CFLAGS) -c $(DEP1).c
clean:
rm $(TARGET) *.o
This is the module .c file:
#include <stdio.h>
#include <stdlib.h>
int add(int x, int y)
{
return(x + y);
}
This is the module .h file:
int add(int, int);
#include "module.h"
in module.c
I am trying to compile a minimal test shared library in FreeBSD using:
FreeBSD clang version 6.0.1 (tags/RELEASE_601/final 335540) (based on LLVM 6.0.1)
Target: x86_64-unknown-freebsd12.0
Thread model: posix
InstalledDir: /usr/bin
test.c
#include "test.h"
int SampleFunction(int a, int b)
{
return a * b;
}
test.h
#ifndef TESTLIB_H
#define TESTLIB_H
extern int SampleFunction(int a, int b);
#endif
Makefile
# Makefile TESTLIB
TEST_OBJS = test.o
TEST_HEADERS = test.h
TEST_LIB = test.so
CC = cc
testlib: $(TEST_OBJS)
$(CC) -fpic -o $(TEST_LIB) $(TEST_OBJS)
# Rebuilt if this Makefile or header changes
$(TEST_OBJS): Makefile $(TEST_HEADERS)
Output:
$ make testlib
cc -O2 -pipe -c test.c -o test.o
cc -fpic -o test.so test.o
/usr/bin/ld: error: undefined symbol: main
>>> referenced by crt1.c:76 (/usr/src/lib/csu/amd64/crt1.c:76)
>>> /usr/lib/crt1.o:(_start)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1
Stop.
make: stopped in /usr/home/user/testlib
As well as adding -shared to the linker stage (as mentioned by Oo.oO), you probably also want to compile with the -fPIC flag as well. So if you are using the makefile implicit rules for the compiling (looks like you are) then you will probably want to add that flag to CFLAGS. I don't think you need it for the linking stage:
# Makefile TESTLIB
TEST_OBJS = test.o
TEST_HEADERS = test.h
TEST_LIB = test.so
CFLAGS += -fPIC
CC = cc
testlib: $(TEST_OBJS)
$(CC) -shared -o $(TEST_LIB) $(TEST_OBJS)
# Rebuilt if this Makefile or header changes
$(TEST_OBJS): Makefile $(TEST_HEADERS)
I prefer using the OS-provided bsd.lib.mk for such building libraries. The following should do the right thing -- whatever it may be:
SHLIB_NAME= testlib
SRCS= test.c
.include <bsd.lib.mk>
(For building executables there is bsd.prog.mk, BTW.)
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
I am new to g++ and Makefile. I am trying to link this BeBOP SMC library, which is in my lib directory. Under the lib directory are bebop_util and sparse_matrix_converter, both of which have already been built without errors. I see libbebop_util.a, libbebop_util.so under bebop_util and libsparse_matrix_converter.a, libsparse_matrix_converter.so under sparse_matrix_converter. Below is the source:
Makefile
CC=g++
CFLAGS=-c -Wall
test.out: test.o
$(CC) -o test.out -Ilib/sparse_matrix_converter/include -Llib/bebop_util \
-Llib/sparse_matrix_converter -lbebop_util -lsparse_matrix_converter test.o
test.o: test.cpp
$(CC) $(CFLAGS) -Ilib/sparse_matrix_converter/include test.cpp
clean:
rm -f test.o test.out
test.cpp
#include <bebop/smc/sparse_matrix.h>
#include <bebop/smc/sparse_matrix_ops.h>
int main(int argc, const char* argv[])
{
struct sparse_matrix_t* A = load_sparse_matrix (MATRIX_MARKET, "sample_input");
destroy_sparse_matrix(A);
return 0;
}
Output:
login3% make
g++ -c -Wall -Ilib/sparse_matrix_converter/include test.cpp
g++ -o test.out -Ilib/sparse_matrix_converter/include -Llib/bebop_util -Llib/sparse_matrix_converter -lbebop_util -lsparse_matrix_converter test.o
test.o: In function `main':
test.cpp:(.text+0x1a): undefined reference to `load_sparse_matrix(sparse_matrix_file_format_t, char const*)'
test.cpp:(.text+0x27): undefined reference to `destroy_sparse_matrix(sparse_matrix_t*)'
collect2: ld returned 1 exit status
make: *** [test.out] Error 1
Please note that test.cpp depends on sparse_matrix_converter, which depends on bebop_util. Would you please let me know what mistakes I may have made? Thanks.
Tom
The BeBOP code looks to be C code but hasn't add the correct C++ guards. Surround your includes with extern "C" to fix that:
extern "C" {
#include <bebop/smc/sparse_matrix.h>
#include <bebop/smc/sparse_matrix_ops.h>
}