how do I link a c file to two executables - c

I have a file called wrapsock.c that has several wrapper functions for the socket.h header file. I have two executables, FTP_client and FTP_server who both need to use the wrapsock.c file. I am having trouble with my makefile to link the wrapsock.c file to both of these programs
Here is my makefile below:
all: ./bin/FTP_client ./bin/FTP_server
bin/FTP_client: main_client.o wrapsock.o
gcc -o bin/FTP_client main_client.o wrapsock.o -lpthread -g
mv main_client.o ./bin
mv wrapsock.o ./bin
bin/FTP_server: main_server.o wrapsock.o
gcc -o bin/FTP_server main_server.o wrapsock.o -lpthread -g
mv main_server.o ./bin
mv wrapsock.o ./bin
main_client.o: src/main_client.c
gcc -c src/main_client.c -g
wrapsock.o: src/wrapsock.c src/wrapsock.h
gcc -c src/wrapsock.c -g
main_server.o: src/main_server.c
gcc -c src/main_server.c -g
clean:
rm ./bin/*.o
rm ./bin/FTP_client
rm ./bin/FTP_server
This is the error I am receiving:
gcc -c src/main_client.c -g
gcc -c src/wrapsock.c -g
gcc -o bin/FTP_client main_client.o wrapsock.o -lpthread -g
mv main_client.o ./bin
mv wrapsock.o ./bin
gcc -o bin/FTP_server main_server.o wrapsock.o -lpthread -g
gcc: error: wrapsock.o: No such file or directory
make: *** [makefile:9: bin/FTP_server] Error 1

mv wrapsock.o ./bin
gcc -o bin/FTP_server main_server.o wrapsock.o -lpthread -g
gcc: error: wrapsock.o: No such file or directory
To move the object is not a good way, create the objects directly into the directory bin as you do for the executable :
all: ./bin/FTP_client ./bin/FTP_server
bin/FTP_client: bin/main_client.o bin/wrapsock.o
gcc -o bin/FTP_client bin/main_client.o bin/wrapsock.o -lpthread -g
bin/FTP_server: bin/main_server.o bin/wrapsock.o
gcc -o bin/FTP_server bin/main_server.o bin/wrapsock.o -lpthread -g
bin/main_client.o: src/main_client.c
gcc -c src/main_client.c -g -o bin/main_client.o
bin/wrapsock.o: src/wrapsock.c src/wrapsock.h
gcc -c src/wrapsock.c -g -o bin/wrapsock.o
bin/main_server.o: src/main_server.c
gcc -c src/main_server.c -g -o bin/main_server.o
clean:
rm ./bin/*.o
rm ./bin/FTP_client
rm ./bin/FTP_server

Not sure why are you moving the binary objects to bin/, but after you've built your client target wrapsock.o is no longer in project root and resides in bin/ instead, so when server target gets its turn, gcc can no longer find it. I would just ditch the moves or if there is a reason for performing them, do so in a separate target that is done only after both binaries have been built (i.e. lists them as prerequisites).

Related

C, Refactoring Makefile

My makefile works however if I erase debutliste.o lecturefichier.o statistiques.o tri.o
from the target compile, it still works I imagine bc they are done in the other .o targets.
Make: link
compile: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
listechainee.o: listechainee.c listechainee.h debutliste.o
gcc -g -Wall -Wextra -std=c11 -c listechainee.c
debutliste.o: debutliste.c debutliste.h lecturefichier.o
gcc -g -Wall -Wextra -std=c11 -c debutliste.c
lecturefichier.o: lecturefichier.c lecturefichier.h statistiques.o
gcc -g -Wall -Wextra -std=c11 -c lecturefichier.c
statistiques.o: statistiques.c statistiques.h tri.o
gcc -g -Wall -Wextra -std=c11 -c statistiques.c
tri.o: tri.c
gcc -g -Wall -Wextra -std=c11 -c tri.c
clean:
rm -rf *.o
link: compile
gcc *.o -o tri
If I understand correctly I should delete the debutliste.o lecturefichier.o statistiques.o tri.o that are inside the .o targets bc they will be executed as dependencies from the target compile and it should look like this?
Make: link
compile: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
listechainee.o: listechainee.c listechainee.h
gcc -g -Wall -Wextra -std=c11 -c listechainee.c
debutliste.o: debutliste.c debutliste.h
gcc -g -Wall -Wextra -std=c11 -c debutliste.c
lecturefichier.o: lecturefichier.c lecturefichier.h
gcc -g -Wall -Wextra -std=c11 -c lecturefichier.c
statistiques.o: statistiques.c statistiques.h
gcc -g -Wall -Wextra -std=c11 -c statistiques.c
tri.o: tri.c
gcc -g -Wall -Wextra -std=c11 -c tri.c
clean:
rm -rf *.o
link: compile
gcc *.o -o tri
Yes. If you are using GNU Make, you can simplify your makefile (per above) by relying on the fact it already has a catalog of rules. Those rules tells make how to compile c files into object files and how to link object files into a binary. The recursive flag -r for rm makes me nervous so I removed it. You probably don't need a separate link step so I use the standard all target instead of compile:
.PHONY: all clean
CFLAGS:=-g -Wall -Wextra -std=c11
all: tri
clean:
rm -f *.o ./tri
tri: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
debutliste.o: debutliste.c debutliste.h
lecturefichier.o: lecturefichier.c lecturefichier.h
listechainee.o: listechainee.c listechainee.h
statistiques.o: statistiques.c statistiques.h
If you want to be fancy you can use a pattern rule %.o: %.c %h that says a given file .o depends on it's corresponding .c and .h files which makes the makefile quite compact:
.PHONY: all clean
CFLAGS:=-g -Wall -Wextra -std=c11
all: tri
clean:
rm -f *.o ./tri
tri: listechainee.o debutliste.o lecturefichier.o statistiques.o tri.o
%.o: %.c %h
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $<
The list of object files is probably just all your c files with a different name. You can write that as:
OBJECTS:=$(patsubst %.c,%.o,$(wildcard *.c))
tri: $(OBJECTS)
However, I don't usually do that step in my projects as the build now become sensitive to temporary .c files that I often create while working.

Tcc Error : "-run is not available in a cross compiler"

I tried compiler TCC(Tiny C compiler: https://bellard.org/tcc/) form source code:
$ pwd
/cygdrive/D/Download/tcc-0.9.27/tcc-0.9.27
Administrator#MS-QMYKYRDOTLFI /cygdrive/D/Download/tcc-0.9.27/tcc-0.9.27
$ ./configure
Binary directory C:/Program Files/tcc
TinyCC directory C:/Program Files/tcc
Library directory C:/Program Files/tcc/libtcc
Doc directory C:/Program Files/tcc/doc
Source path .
C compiler gcc (11.2)
Target OS CYGWIN_NT-10.0
CPU x86_64
Config WIN32
Creating config.mak and config.h
config.h is unchanged
after configutre, make, make install.
then, i run the fib.c, it show error message:
$ pwd
/cygdrive/c/Program Files/tcc/examples
Administrator#MS-QMYKYRDOTLFI /cygdrive/c/Program Files/tcc/examples
$ ../tcc.exe -run fib.c 12
tcc: error: -run is not available in a cross compiler
This is run on Windows 10, Cygwin64 Terminal.
I check the source code, in libtcc.c, there are these lines:
#ifndef TCC_IS_NATIVE
tcc_error("-run is not available in a cross compiler");
#endif
Maybem the reason is, when i "make", i didnot add _DTCC_IS_NATIVE? I don't know.
If i download tcc-0.9.27-win64-bin form web, '-run' works! Please help me , how to generate a tcc.exe can use '-run'.
Thanks!
Add CPPFLAGS or CFLAGS , also did not work:
$ ./configure CPPFLAGS="-DTCC_IS_NATIVE"
configure: WARNING: unrecognized option CPPFLAGS=-DTCC_IS_NATIVE
Binary directory C:/Program Files/tcc
TinyCC directory C:/Program Files/tcc
Library directory C:/Program Files/tcc/libtcc
Doc directory C:/Program Files/tcc/doc
Source path .
C compiler gcc (11.2)
Target OS CYGWIN_NT-10.0
CPU x86_64
Config WIN32
Creating config.mak and config.h
config.h is unchanged
Put CPPFLAGS before configure, also did not work:
Administrator#MS-QMYKYRDOTLFI /cygdrive/D/Download/tcc-0.9.27/tcc-0.9.27
$ CPPFLAGS=-DTCC_IS_NATIVE ./configure
Binary directory C:/Program Files/tcc
TinyCC directory C:/Program Files/tcc
Library directory C:/Program Files/tcc/libtcc
Doc directory C:/Program Files/tcc/doc
Source path .
C compiler gcc (11.2)
Target OS CYGWIN_NT-10.0
CPU x86_64
Config WIN32
Creating config.mak and config.h
config.h is unchanged
$ make
gcc -o tcc.o -c tcc.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o libtcc.o -c libtcc.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o tccpp.o -c tccpp.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o tccgen.o -c tccgen.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o tccelf.o -c tccelf.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o tccasm.o -c tccasm.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o tccrun.o -c tccrun.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o x86_64-gen.o -c x86_64-gen.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o x86_64-link.o -c x86_64-link.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o i386-asm.o -c i386-asm.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
gcc -o tccpe.o -c tccpe.c -DTCC_TARGET_X86_64 -DTCC_TARGET_PE -DLIBTCC_AS_DLL -DONE_SOURCE=0 -Wall -g -O2 -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result -I.
In function ‘pe_write’,
inlined from ‘pe_output_file’ at tccpe.c:1975:19:
tccpe.c:677:9: warning: ‘strncpy’ output may be truncated copying 8 bytes from a string of length 31 [-Wstringop-truncation]
677 | strncpy((char*)psh->Name, sh_name, sizeof psh->Name);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc -shared -o libtcc.dll libtcc.o tccpp.o tccgen.o tccelf.o tccasm.o tccrun.o x86_64-gen.o x86_64-link.o i386-asm.o tccpe.o -static
gcc -o tcc.exe tcc.o libtcc.dll -static
make[1]: Entering directory '/cygdrive/D/Download/tcc-0.9.27/tcc-0.9.27/lib'
../tcc.exe -c libtcc1.c -o libtcc1.o -B../win32 -I../include
../tcc.exe -c alloca86_64.S -o alloca86_64.o -B../win32 -I../include
../tcc.exe -c alloca86_64-bt.S -o alloca86_64-bt.o -B../win32 -I../include
../tcc.exe -c ../win32/lib/chkstk.S -o chkstk.o -B../win32 -I../include
../tcc.exe -c bcheck.c -o bcheck.o -B../win32 -I../include
../tcc.exe -c ../win32/lib/crt1.c -o crt1.o -B../win32 -I../include
../tcc.exe -c ../win32/lib/crt1w.c -o crt1w.o -B../win32 -I../include
../tcc.exe -c ../win32/lib/wincrt1.c -o wincrt1.o -B../win32 -I../include
../tcc.exe -c ../win32/lib/wincrt1w.c -o wincrt1w.o -B../win32 -I../include
../tcc.exe -c ../win32/lib/dllcrt1.c -o dllcrt1.o -B../win32 -I../include
../tcc.exe -c ../win32/lib/dllmain.c -o dllmain.o -B../win32 -I../include
../tcc.exe -ar rcs ../libtcc1.a libtcc1.o alloca86_64.o alloca86_64-bt.o chkstk.o bcheck.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
make[1]: Leaving directory '/cygdrive/D/Download/tcc-0.9.27/tcc-0.9.27/lib'
./tcc.exe -impdef libtcc.dll -o libtcc.def
makeinfo tcc-doc.texi || true
Can't locate Texinfo/ModulePath.pm in #INC (you may need to install the Texinfo::ModulePath module) (#INC contains: /mingw64/share/texinfo /usr/local/lib/perl5/site_perl/5.32/x86_64-cygwin-threads /usr/local/share/perl5/site_perl/5.32 /usr/lib/perl5/vendor_perl/5.32/x86_64-cygwin-threads /usr/share/perl5/vendor_perl/5.32 /usr/lib/perl5/5.32/x86_64-cygwin-threads /usr/share/perl5/5.32) at /cygdrive/d/Program Files/GNU Octave/Octave-6.3.0/mingw64/bin/makeinfo line 82.
BEGIN failed--compilation aborted at /cygdrive/d/Program Files/GNU Octave/Octave-6.3.0/mingw64/bin/makeinfo line 85.
$ make install
mkdir -p "C:/Program Files/tcc" && install -m755 tcc.exe libtcc.dll "C:/Program Files/tcc"
mkdir -p "C:/Program Files/tcc/lib" && install -m644 ./win32/lib/*.def "C:/Program Files/tcc/lib"
mkdir -p "C:/Program Files/tcc/lib" && install -m644 libtcc1.a "C:/Program Files/tcc/lib"
mkdir -p "C:/Program Files/tcc/include" && install -m644 ./include/*.h ./tcclib.h "C:/Program Files/tcc/include"
mkdir -p "C:/Program Files/tcc/include" && cp -r ./win32/include/. "C:/Program Files/tcc/include"
mkdir -p "C:/Program Files/tcc/examples" && cp -r ./win32/examples/. "C:/Program Files/tcc/examples"
mkdir -p "C:/Program Files/tcc/examples" && install -m644 ./tests/libtcc_test.c "C:/Program Files/tcc/examples"
mkdir -p "C:/Program Files/tcc/libtcc" && install -m644 ./libtcc.h libtcc.def "C:/Program Files/tcc/libtcc"
mkdir -p "C:/Program Files/tcc/doc" && install -m644 ./win32/tcc-win32.txt tcc-doc.html "C:/Program Files/tcc/doc"
Administrator#MS-QMYKYRDOTLFI /cygdrive/D/Download/tcc-0.9.27/tcc-0.9.27
$ cd -
/cygdrive/c/Program Files/tcc/examples
Administrator#MS-QMYKYRDOTLFI /cygdrive/c/Program Files/tcc/examples
$ pwd
/cygdrive/c/Program Files/tcc/examples
Administrator#MS-QMYKYRDOTLFI /cygdrive/c/Program Files/tcc/examples
$ ../tcc.exe -run fib.c 12
tcc: error: -run is not available in a cross compiler

Makefile compiling and linking problems

So I've been trying to search for a solution that Im having with my make file currently. I get the error:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
So I have 5 files in my src folder: find.c, rebalance.c, remove.c, lib.c, and insert.c. In my src/bin folder I just have main.c and in another folder 'include' outside of src I have bst.h. This is what my makefile looks like:
all: static bin shared
mkdir -p build/bin
mkdir -p build/lib
mkdir -p build/objects
mv *.o build/objects
mv *.a build/lib
mv main build/bin
mv libbst.so build/lib
static:
gcc src/lib.c -c -I include
gcc src/find.c -c -I include
gcc src/insert.c -c -I include
gcc src/rebalance.c -c -I include
gcc src/remove.c -c -I include
ar rcs libbst.a find.o insert.o lib.o rebalance.o remove.o
shared:
gcc -c -o lib.o src/lib.c
gcc -c -o find.o src/find.c
gcc -c -o insert.o src/insert.c
gcc -c -o rebalance.o src/rebalance.c
gcc -c -o remove.o src/remove.c
gcc -shared -o libbst.so find.o insert.o lib.o rebalance.o remove.o
bin:
gcc src/lib.c -c -I include
gcc lib.o -o lib -lbst -L.
gcc src/bin/main.c -c -I include
gcc main.o -o main -lbst -L.
clean:
rm -rf *.so *.a *.o main build
install:
Im assuming that I'm just not using the right commands to link everything together. This always fails in the 'bin' section of the Makefile. I would really appreciate any help or advice on what I can do here, im kind of stumped right now.

Failed to do 'make' on .c and .s files using Mac

I'm trying to compile a simple project with .c and .s files using my Mac.
When I run 'make' it goes threw on the compilation, and I think it failed when its trying to link (not sure).
Here is the error it shows:
gcc -m32 -g -Wall -c -o main.o main.c
gcc -m32 -g -Wall -c -o numbers.o numbers.c
nasm -g -f macho -w+all -o add.o add.s
gcc -m32 -g -Wall -o run main.o numbers.o add.o
ld: malformed file
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libSystem.tbd:4:18: error: unknown enumerated scalar
platform: zippered
^~~~~~~~
file '/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/lib/libSystem.tbd'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [run] Error 1
and I'll add the makefile as well:
run: main.o numbers.o add.o
gcc -m32 -g -Wall -o run main.o numbers.o add.o
main.o: main.c
gcc -m32 -g -Wall -c -o main.o main.c
numbers.o: numbers.c
gcc -m32 -g -Wall -c -o numbers.o numbers.c
add.o: add.s
nasm -g -f macho -w+all -o add.o add.s
.PHONY: clean
clean:
rm -f *.o run

Is it possible to compile svdlibc on a mac (64 bit)?

I'm trying to compile svdlibc on a 64 bit mac. Running the make file returns the error message:
main.c:1: error: CPU you selected does not support x86-64 instruction set
main.c:1: error: CPU you selected does not support x86-64 instruction set
make: *** [main.o] Error 1
Which doesn't make much sense.
The make file is:
# Linux or Windows:
CC = gcc -Wall -O4 -march=i486
# CC = icc -w1 -O3 -march=i486
# Macintosh:
ifeq ($(HOSTTYPE),powerpc)
CC = cc -pipe -O3 -Wall -fno-common -arch ppc
endif
LIBS=-lm
OBJ=svdlib.o svdutil.o las2.o
svd: Makefile main.o libsvd.a
${CC} ${CFLAGS} -o svd main.o libsvd.a ${LIBS}
mv -f $# ${HOSTTYPE}/$#
ln -s ${HOSTTYPE}/$# $#
main.o: Makefile main.c svdlib.h
${CC} ${CFLAGS} -c main.c
libsvd.a: ${HOSTTYPE} ${OBJ}
rm -f $# ${HOSTTYPE}/$#
ar cr $# ${OBJ}
ranlib $#
mv -f $# ${HOSTTYPE}/$#
ln -s ${HOSTTYPE}/$# $#
svdlib.o: Makefile svdlib.h svdlib.c
${CC} ${CFLAGS} -c svdlib.c
svdutil.o: Makefile svdutil.c svdutil.h
${CC} ${CFLAGS} -c svdutil.c
las2.o: Makefile las2.c svdlib.h svdutil.h
${CC} ${CFLAGS} -c las2.c
clean:
rm *.o
$(HOSTTYPE):
if test ! -d $(HOSTTYPE); \
then mkdir $(HOSTTYPE); fi
Editing the make file to alter the -march flag lets the compilation proceed but apparently the linking fails with:
ld: lto: could not merge in main.o because Invalid ALLOCA record for
architecture x86_64
Has anyone done this? Or is there a different svd library that I should use instead? (For large sparse matrices?)
EDIT: porneL seems to have found the problem. Changing the top line in the makefile to:
CC = gcc -Wall -O3 -march=x86-64
compilation work. Haven't tested the results yet, but looks very promising.
-O4 causes this for some reason. Use -O3 instead.
You could try with port ( http://www.macports.org/ ) it seems it s availablee :
svdlibc #1.34 (math, science)
SVDLIBC is a C library to perform singular value decomposition
Basically you ll install macports then , sudo port install svdlibc.

Resources