Linux shared object compilation issue - c

My Makefile was like this earlier.
export SOURCE1 = source1.c \
1.c \
2.c \
3.c
export SOURCE2 = source2.c \
1.c
all:
gcc -Wall -W -g -O2 ${SOURCE1} -lm -lipc -o source1
gcc -Wall -W -g -O2 ${SOURCE2} -lm -lipc -o source2
This one works fine. And, I wanted to create a shared object which comprises 1.c, 2.c and 3.c. Consequently I changed my Makefile to
export LIB_SOURCE 1.c 2.c 3.c
export SOURCE1 = source1.c
export SOURCE2 = source2.c
all:
gcc -Wall -W -g -O2 ${LIB_SOURCE} -o libsrc.so.1
ln -sf libsrc.so.1 libsrc.so.0
ln -sf libsrc.so.0 libsrc.so
gcc -Wall -W -g -O2 ${SOURCE1} -lm -lipc -lsrc -o source1
gcc -Wall -W -g -O2 ${SOURCE2} -lm -lipc -lsrc -o source2
The make failed while compiling source2, saying it
src.so: undefined reference to 'var1'
The var1 is defined in 3.c which is not needed by source2. Since it's included in the library it's failing looking at it. How to move on with this error.
Thanks,

I was able to get your makefile to work with a couple of small adjustments:
all:
gcc -Wall -W -g -O2 -shared ${LIB_SOURCE} -o libcsrc.so
gcc -Wall -W -g -O2 -L. ${SOURCE1} -lm -lsrc -o source1
gcc -Wall -W -g -O2 -L. ${SOURCE2} -lm -lsrc -o source2
(I removed -lipc because I don't have that library handy.) But I suggest a slightly different approach once the above is working perfectly for you. Since you are constructing the library libsrc.so, make a separate rule for it, and a separate rule for each of the executables, and use prerequisite lists:
all: source1 source2
source1: source1.c libcsrc.so
gcc -Wall -W -g -O2 -L. source1.c -lm -lsrc -o source1
source1: source2.c libcsrc.so
gcc -Wall -W -g -O2 -L. source2.c -lm -lsrc -o source2
libcsrc.so: ${LIB_SOURCE}
gcc -Wall -W -g -O2 -shared ${LIB_SOURCE} -o libcsrc.so
Then you can put in automatic variables, and combine the source1 and source2 rules:
all: source1 source2
source1 source2: % : %.c libcsrc.so
gcc -Wall -W -g -O2 -L. $< -lm -lsrc -o $#
libcsrc.so: ${LIB_SOURCE}
gcc -Wall -W -g -O2 -shared $^ -o $#

Related

R_X86_64_PC32 against undefined symbol `WinMain' on cygwin

When I compile my code on the command line, there are no problems:
$ gcc -Wall -O2 -o mess main.c getmatrix.c toktoint.c prtmatrix.c getdist.c
But when I compile via make, it fails:
$ make clean
$ make
/usr/bin/gcc -O2 -Wall -c toktoint.c -o toktoint.o
/usr/bin/gcc -O2 -Wall -c getmatrix.c -o getmatrix.o
/usr/bin/gcc -O2 -Wall -c prtmatrix.c -o prtmatrix.o
/usr/bin/gcc -O2 -Wall -c getdist.c -o getdist.o
/usr/bin/gcc -O2 -Wall -c -o main.o main.c
/usr/bin/gcc -O2 -Wall -o mess toktoint.o
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /usr/lib/gcc/x86_64-pc-cygwin/10/../../../../lib/libcygwin.a(libcmain.o): in function `main':
/usr/src/debug/cygwin-3.1.7-1/winsup/cygwin/lib/libcmain.c:37: undefined reference to `WinMain'
/usr/src/debug/cygwin-3.1.7-1/winsup/cygwin/lib/libcmain.c:37:(.text.startup+0x82): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain'
collect2: error: ld returned 1 exit status
make: *** [Makefile:44: mess] Error 1
Here is my Makefile:
CC=/usr/bin/gcc
OPTIMIZATION=2
CFLAGS=-O$(OPTIMIZATION) -Wall
LFLAGS=
TARGET=mess
OBJECTS=toktoint.o \
getmatrix.o \
prtmatrix.o \
getdist.o \
main.o
SOURCES=toktoint.c \
getmatrix.c \
prtmatrix.c \
getdist.c \
main.c
HEADERS=getmatrix.h \
toktoint.h \
prtmatrix.h \
getdist.h
all: $(TARGET)
mess: $(OBJECTS)
$(CC) $(CFLAGS) -o $# $<
%.o: %.c %.h
$(CC) $(CFLAGS) -c $< -o $#
clean:
#rm -f $(OBJECTS) $(TARGET)
I tried changing various flags, such as "-m64". And other suggestions which I found on stackoverflow, but no success.
If I compile each module on the command line, it also works:
$ make clean
$ gcc -O2 -Wall -c toktoint.c -o toktoint.o
$ gcc -O2 -Wall -c getmatrix.c -o getmatrix.o
$ gcc -O2 -Wall -c prtmatrix.c -o prtmatrix.o
$ gcc -O2 -Wall -c getdist.c -o getdist.o
$ gcc -O2 -Wall -c main.c -o main.o
$ gcc -Wall -O2 -o mess main.o getdist.o getmatrix.o prtmatrix.o toktoint.o
So it appears the problem is with make or Makefile.
Look at the output from make again, especially the linker line:
/usr/bin/gcc -O2 -Wall -o mess toktoint.o
It does not build with all the object files. Most notably, it misses main.o which I assume contains your main function.
The variable $< is only
The name of the first prerequisite
(from this make manual, emphasis mine).
To get all prerequisites (all object files) use $^:
mess: $(OBJECTS)
$(CC) $(CFLAGS) -o $# $^

error: cannot specify -o when generating multiple output files

How to fix this error?
I am trying to compile the C project, but I get such error
Alekseys-MBP:mmn14 aleksey$ make
gcc -Wall -ansi -pedantic -c -o assembler.o assembler.c
gcc -Wall -ansi -pedantic -c -o utils.o utils.c
gcc -Wall -ansi -pedantic -c -o symbol_table.o symbol_table.c
gcc -Wall -ansi -pedantic -c -o file_scan.o file_scan.c
file_scan.c:323:2: warning: no newline at end of file [-Wnewline-eof]
}
^
1 warning generated.
gcc -Wall -ansi -pedantic -c -o data_block.o data_block.c
gcc -Wall -ansi -pedantic -c -o commands.o commands.c
gcc -Wall -ansi -pedantic assembler.o utils.o symbol_table.o file_scan.o utils.h data_block.o commands.o -o assembler
clang: error: cannot specify -o when generating multiple output files
make: *** [assembler] Error 1
there is my makefile
EXEC_FILE = assembler
C_FILES = assembler.c utils.c symbol_table.c file_scan.c utils.h data_block.c commands.c
H_FILES = common.h symbol_table.h data_block.h commands.h file_scan.h
O_FILES = $(C_FILES:.c=.o)
all: $(EXEC_FILE)
$(EXEC_FILE): $(O_FILES)
gcc -Wall -ansi -pedantic $(O_FILES) -o $(EXEC_FILE)
%.o: %.c $(H_FILES)
gcc -Wall -ansi -pedantic -c -o $# $<
clean:
rm -f *.o $(EXEC_FILE)
What am I doing wrong?
This list of C files:
C_FILES = assembler.c utils.c symbol_table.c file_scan.c utils.h data_block.c commands.c
contains a header, file utils.h.
When this statement:
O_FILES = $(C_FILES:.c=.o)
constructs the list of object files, the substitution .c=.o does not alter utils.h, which results in O_FILES containing a header file. Then this build command:
gcc -Wall -ansi -pedantic $(O_FILES) -o $(EXEC_FILE)
asks GCC to do its default actions with the files, which is to link the object files and write an executable file and to “precompile” (analyze) the header file and write a “precompiled header” data file. Thus, you have two output files.
To fix this, remove utils.h from C_FILES and put it in H_FILES.

What is the correct or efficient form to write a Makefile when you need two executables that use the same library?

I'm trying to write a Makefile to compile two programs that include the same .h (also mine), but with my actual Makefile if I type "make" in command line twice in a row, I don't get "bla bla is up to date", it recompile part of the stuff when it's not necessary. Any way to do this in a more efficient form?
Context
producer.c and consumer.c #include random_numbers.h in order to generate random numbers to its functions.
My Makefile
CC = gcc
FLAGS = -Wall -g
LIBS = -lrt -lpthread
HEADER_FILES_DIR = .
INCLUDES = -I $(HEADER_FILES_DIR)
SRCS = e1_producer.c e1_consumer.c $(HEADER_FILES_DIR)/random_num.c
OBJ = $(SRC:.c=.co)
DEPS = $(HEADER_FILES_DIR)/random_num.h
all: e1_producer e1_consumer
random_num.o: random_num.c random_num.h
$(CC) $(FLAGS) -c random_num.c
e1_producer: e1_producer.o random_num.o
$(CC) $(FLAGS) -o producer e1_producer.o random_num.o $(LIBS)
e1_producer.o: e1_producer.c
$(CC) $(FLAGS) -c e1_producer.c $(LIBS)
e1_consumer: e1_consumer.o random_num.o
$(CC) $(FLAGS) -o consumer e1_consumer.o random_num.o $(LIBS)
e1_consumer.o: e1_consumer.c
$(CC) $(FLAGS) -c e1_consumer.c $(LIBS)
clean:
rm producer consumer *.o
Output after two consecutive "make" in the command line
$ make
$ gcc -Wall -g -c e1_producer.c -lrt -lpthread
$ gcc -Wall -g -c random_num.c
$ gcc -Wall -g -o producer e1_producer.o random_num.o -lrt -lpthread
$ gcc -Wall -g -c e1_consumer.c -lrt -lpthread
$ gcc -Wall -g -o consumer e1_consumer.o random_num.o -lrt -lpthread
$ make
gcc -Wall -g -o producer e1_producer.o random_num.o -lrt -lpthread
gcc -Wall -g -o consumer e1_consumer.o random_num.o -lrt -lpthread
Why is this happening? When I do the same with another single program the second $ make returns me "nothing to do, bla bla is up to date"

Use Azure Iothub_client examples in own code

I'm trying to use the AMQPoverWebsockets-Client example from the C-SDK of Azure-iothub.
How do I link the specific libraries to the makefile to compile it successfully?
I tried to write the path down in my makefile. But it didn't work.
Here is my makefile so far:
SENSOR=mcp9808
SENSOR2=adxl345x
SENSOR3=init
SENSOR4=filestorage
IOT1=src/iothubtransporthttp.c.o
IOT2=src/iothub_client_ll.c.o
IOT3=src/iothub_message.c.o
IOT4=src/platform_linux.c.o
IOT5=src/crt_abstractions.c.o
all:
gcc -Wall -c $(SENSOR).c -o $(SENSOR).o -lm -lwiringPi -lrt
gcc -Wall -c $(SENSOR2).c -o $(SENSOR2).o -lm -lwiringPi -lrt
gcc -Wall -c $(SENSOR4).c -o $(SENSOR4).o -lm -lwiringPi -lrt
gcc -Wall -c $(SENSOR3).c -o $(SENSOR3).o -lm -lrt `pkg-config --cflags --libs glib-2.0`
#gcc -Wall $(IOT1) $(IOT2) $(IOT3) $(IOT4) $(IOT5) iothub_client_sample_http.c -o iot_client -lm -lrt
gcc -Wall $(SENSOR).o $(SENSOR2).o $(SENSOR3).o $(SENSOR4).o main.c -o main -lm -lwiringPi -lrt `pkg-config --cflags --libs glib-2.0`
clean:
rm *.o > /dev/null 2>&1 &

gcc builds with -o but not -o3?

My Makefile looks like this:
CC=gcc
CFLAGS=-Wall -Wextra -std=c99 -pedantic
OBJECTS=main.o Scene.o Matrix.o Vector.o Triangle.o Color.o Raster.o
render: $(OBJECTS)
$(CC) $(CFLAGS) -lm -o render -g $(OBJECTS)
rm $(OBJECTS)
clean:
rm -f render*
This builds my executable with no errors, but when I change -o to -o2 or -o3, I get the error:
gcc -Wall -Wextra -std=c99 -pedantic -c -o main.o main.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Scene.o Scene.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Matrix.o Matrix.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Vector.o Vector.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Triangle.o Triangle.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Color.o Color.c
gcc -Wall -Wextra -std=c99 -pedantic -c -o Raster.o Raster.c
gcc -Wall -Wextra -std=c99 -pedantic -lm -o3 render -g main.o Scene.o Matrix.o Vector.o Triangle.o Color.o Raster.o
gcc.exe: error: render: No such file or directory
make: *** [render] Error 1
There could be some error in my code detected by the optimization flags, but as I don't get any error messages before this it's hard to know what's going wrong. I'm using MinGW/MSYS on Windows 7.
-o render means create the output file with the name render.
Now you are changing this -o to -o3 which is incorrect. Instead you need to keep -o render as it is and add a -O3 flag for optimization. Note the capital letter O.
-o is the output file flag. You were thinking of -O (capital).

Resources