I have an makefile but doesn't work. The error in terminal is this: cc -shared -o build/liblcthw.so src/lcthw/list.o
/usr/bin/ld: src/lcthw/list.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
src/lcthw/list.o: error adding symbols: Bad value
I need help to put the gcc comand gcc -shared -o target.so -fPIC target.c, i don't how to put the target.c instead list.o
This is the makefile:
CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/liblcthw.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target Build
all: $(TARGET) $(SO_TARGET) tests
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build:
#mkdir -p build
#mkdir -p bin
# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
valgrind:
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
# The Cleaner
clean:
rm -rf build $(OBJECTS) $(TESTS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
# The Install
install: all
install -d $(DESTDIR)/$(PREFIX)/lib/
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
# The Checker
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
check:
#echo Files with potentially dangerous functions.
#egrep $(BADFUNCS) $(SOURCES) || true
Your objects for liblcthw.a are built with -fPIC. Objects for liblcthw.so are not built with this setting.
Try changing rule:
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
to:
$(SO_TARGET): $(TARGET)
$(CC) -shared -o $# $^
Since the required objects are already in liblcthw.a.
Or, alternatively:
$(SO_TARGET): CFLAGS += -fPIC
$(SO_TARGET): $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
Related
I'm trying to compile my C project using clang (I'm on MacOS Monterry) and a Makefile, but I keep getting the same error from clang in the command line:
> make
gcc -c src/ji.c src/main.c -o src/ji.o
clang: error: cannot specify -o when generating multiple output files
make: *** [src/ji.o] Error 1
These are the only files I have in the project so far:
src/main.c
src/ji.c
include/ji.h
The Makefile looks like this:
cc = gcc
src = $(wildcard src/*.c)
obj = $(src:.c=.o)
exec = ji
$(exec): $(obj)
$(cc) -Iinclude $< -o build/$#
%.o: %.c
$(cc) -c $(src) -o $#
clean:
-rm src/*.o
-rm ji
From YouTube videos I've seen, this should be the ideal Makefile for the project but no matter what I change I get the error.
There are a few issues:
-Iinclude needs to be on the %.o: %.c rule command
In %.o: %.c, we don't want $(src) but rather $<
We want patsubst to get the .o list obj
The $(exec) target doesn't match the -o option
The clean doesn't match the placement of the executable
Here's a refactored version (e.g. one way to do this--there are others):
cc = gcc
src = $(wildcard src/*.c)
obj = $(patsubst %.c,%.o,$(src))
exec = build/ji
$(exec): $(obj)
mkdir -p build
$(cc) $^ -o $#
%.o: %.c
$(cc) -c $< -o $# -Iinclude
clean:
rm -f src/*.o
rm -fr build
Here's the output of make:
gcc -c src/ji.c -o src/ji.o -Iinclude
gcc -c src/main.c -o src/main.o -Iinclude
mkdir -p build
gcc src/ji.o src/main.o -o build/ji
Here's the output of make clean:
rm -f src/*.o
rm -fr build
I want to compile a C program from GitHub on Windows 7 and get an error that a file is not found. I have installed MinGW Make and its dependancies. I think maybe this program is only intended to run on Linux.
The Console output:
E:\work-c\iso2opl-clone\iso2opl>make
gcc -std=gnu99 -pedantic -usr\include -usr\local\inc
lude -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -c isofs.c -o isofs.o
process_begin: CreateProcess(NULL, gcc -std=gnu99 -pedantic -F:\programs\mingw\i
nclude -F:\programs\mingw\local\include -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SO
URCE -c isofs.c -o isofs.o, ...) failed.
make (e=2): Le fichier spécifié est introuvable.
make: *** [isofs.o] Erreur 2
the makefile:
CC = gcc
CFLAGS = -std=gnu99 -pedantic -I/usr/include -I/usr/local/include -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
#CFLAGS += -DDEBUG
ifeq ($(_WIN32),1)
CFLAGS += -D_WIN32
endif
OBJS = isofs.o \
iso2opl.o
all: $(TARGET)
rm-elf:
-rm -f $(TARGET) $(OBJS)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm -r $(OBJS) $(TARGET)
I don't know maybe the paths are wrongs.
Best Regards
Try to run the make in the MSYS2 shell (https://www.msys2.org/). I was able to build the sources from https://github.com/arcadenea/iso2opl without issue.
I have started to move some of my atmega code into a static library for easier use in the future. This has some issues with ussing the library. I have compiled and linked againsed it, and it runs. The problem is the USART function that takes an array as input seems to just send noise to my com port. It worked fine before i put the code in a static lib.
Makefile library
## General Flags
PROJECT = june
MCU = atmega328p
TARGET = libJune.a
CC = avr-g++
F_CPU := 1200000LL
## Options common to compile, link and
assembly rules
COMMON = -fpack-struct -fshort-enums -
funsigned-char -funsigned-bitfields -
mmcu=$(MCU) -DF_CPU=$(F_CPU)
## Compile options common for all C
compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -Os -MD -MP -MT -MF
#CFLAGS += -MD -MP -MT $(*F).o -MF
dep/$(#F)
## Objects that must be built in order
to link
OBJECTS := adc.o pwm.o message.o
messagehandler.o
messagetranslationsenter.o usart.o
## Build
all: $(TARGET)
## Compile
adc.o: adc.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
pwm.o: pwm.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
message.o: message.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
messagehandler.o: messagehandler.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
messagetranslationsenter.o:
messagetranslationsenter.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
usart.o: usart.cpp
$(CC) $(INCLUDES) $(CFLAGS) -c $<
## Archive into a library file (.a)
$(TARGET): $(OBJECTS)
avr-ar -r $(TARGET) $(OBJECTS)
## Clean target
.PHONY: clean
clean:
-rm -rf $(OBJECTS) $(TARGET) #dep/*
Makefile program
# the GNU make program
#
VERSION := 0.1
PROGRAM_NAME := heater$(VERSION)
# Chip and programmer
DEVICE_PROGRAMMER := usbtiny
CPU_AVRDUDE := m328p
MCU := atmega328p
F_CPU := 1200000LL
LIB_PATH := $(JUNE_ROOT)/avr
LIBS := -lJune -lm
INCLUDES := -I$(JUNE_ROOT)/avr
# FLAGS
CF := -c -Os -fpack-struct - fshort-enums -funsigned-char -funsigned- bitfields -mmcu=$(MCU) -DF_CPU=$(F_CPU)
$(INCLUDES)
LF := -Os -MD -MP -mmcu=$(MCU) -MT -static -L$(LIB_PATH) $(LIBS)
# TOOLS
CC := avr-g++
avrdude ?= avrdude
OBJECTS = main.o
all: $(PROGRAM_NAME)
main.o: main.cpp
$(CC) $(CF) -c $<
$(PROGRAM_NAME): $(OBJECTS)
$(MAKE) -C $(JUNE_ROOT)/avr
$(CC) -o $(PROGRAM_NAME) $(OBJECTS)
$(LF)
$(PROGRAM_NAME).hex: $(PROGRAM_NAME)
avr-objcopy -O ihex -R .eeprom
$(PROGRAM_NAME) $(PROGRAM_NAME).hex
.PHONY: flash
flash: programmedDevice
clean:
-rm -f *.o *.hex *.elf
programmedDevice_*.time
programmedDevice: $(PROGRAM_NAME).hex
$(avrdude) -c $(DEVICE_PROGRAMMER) -p
$(CPU_AVRDUDE) -v -U
flash:w:$(PROGRAM_NAME).hex
touch programmedDevice_$(CPU_GCC).time
$(PROGRAM_NAME)_$(CPU_GCC).hex:
$(Ofiles)
$(CC) $(LF) -o
$(PROGRAM_NAME)_$(CPU_GCC).elf
$(Ofiles)
$(avr_objcopy) -j .text -j .data -O
ihex $(PROGRAM_NAME)_$(CPU_GCC).elf
$(PROGRAM_NAME)_$(CPU_GCC).hex
clean:
-rm -f *.o *.hex *.elf
programmedDevice_*.time
$(MAKE) -C $(JUNE_ROOT)/avr clean
dumpchip_srec:
$(avrdude) -c $(DEVICE_PROGRAMMER)
-p $(CPU_AVRDUDE) -U
lfuse:r:lfuse_$(CPU_GCC).hex:i -U
hfuse:r:hfuse_$(CPU_GCC).hex:i -U
efuse:r:efuse_$(CPU_GCC).hex:i -U
eeprom:r:eeprom_$(CPU_GCC).hex:i -U
flash:r:flash_$(CPU_GCC).hex:i -U
lock:r:lock_$(CPU_GCC).hex:i -U
signature:r:sig_$(CPU_GCC).hex:i
dumpchip:
$(avrdude) -c $(DEVICE_PROGRAMMER) -p
$(CPU_AVRDUDE) -U
lfuse:r:lfuse_$(CPU_GCC).bin:r -U
hfuse:r:hfuse_$(CPU_GCC).bin:r -U
eeprom:r:eeprom_$(CPU_GCC).bin:r -U
flash:r:flash_$(CPU_GCC).bin:r -U
lock:r:lock_$(CPU_GCC).bin:r -U
signature:r:sig_$(CPU_GCC).bin:r -U
efuse:r:efuse_$(CPU_GCC).bin:r
check:
$(avrdude) -v -c
$(DEVICE_PROGRAMMER) -p $(CPU_AVRDUDE)
This is the part of the test software, that calls the usart function from the static library, but I can only read noise from the com port it sends data too.
while(true)
{
//
USART_putstring("Test");
_delay_ms(5000);
}
I think there is a compiler flag missing that i can not find. Everything is running fine if I add the usart files to the program and compile it. The problem is when the files are put in a static library.
Edit:
it works when i put the define F_CPU in the source file, instead of -DF_CPU=$(F_CPU) from the Makefile
I am using pro*c in AIX,I want make my .pc file compile to a .so libary. And link it. This is my directory:
ls
connect.pc func.c get_log.pc main.c makefile sql_err.pc
This is my makefile:
#Makefile
CC = cc -g -brtl
CFLAGS = -g -c
ESQL = proc
RM = rm -f
MYHOME = /home/xxx
OBJ = main.o func.o
LIBOBJ = get_log.o connect.o sql_err.o
DBINC = -I$(ORACLE_HOME)/precomp/public
DBLIB = -L$(ORACLE_HOME)/lib -lclntsh
INCLUDE = -I$(MYHOME)/include
.SUFFIXES: .pc .c .o
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
clean:
rm -f *.o *.lis
when I make I get this:
.......
cc -g -brtl -o sql_err.o -g -c sql_err.c -I/home/xxx/include -I/oracle/product/10.2.0/precomp/public -L/oracle/product/10.2.0/lib -lclntsh
rm -f sql_err.c
rm -f sql_err.lis
cc -g -brtl -qmkshrobj -o libmydb.so get_log.o connect.o sql_err.o -L/oracle/product/10.2.0/lib -lclntsh
mv libmydb.so /home/xxxlib
when it done mv libmydb.so ,it exit!!!without wrong message.why?? I also need my .c to compile to .o and finally to an executable file query link libmydb.so.
when I change the squeuce like this put .c.o before .pc.o:
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
it give this message,although I have libmydb.so last step:
prepaid(wmfe)/home/xxx/src>make
cc -g -brtl -c -g -c main.c -I/home/xxx/include
cc -g -brtl -c -g -c func.c -I/home/xxx/include
cc -o query main.o func.o -L/home/xxx/lib -lmydb
ld: 0706-006 Cannot find or open library file: -l mydb
ld:open(): A file or directory in the path name does not exist.
make: 1254-004 The error code from the last command is 255.
Stop.
I can't handle this ,very strange,Help!!
By default make will make the first rule in your makefile, but it must not start with a dot. So the default rule in your makefile is libmydb.so and that is being built.
That rule is only dependent on the LIBOBJ and OBJ is not a dependency so it doesn't care about those. It doesn't exit with no reason, it exits because it has done the job you defined for it. There is no error to report.
If you change the order then the default rule is changed and it tries to compile query. This has no dependencies to the library, so it doesn't try to compile that.
If you want to compile everything you should have, for example, a rule all that lists the dependencies. In this case probably libmydb.so and query at least, in correct order. If this is the first rule it will be the default and your compilation will succeed.
I have a sample project that I'm working with from a book "Learn C the hard way". But I can't make it compile.
I believe there is a problem with my Makefile. What I'm trying to do is build a library and then call some functions from it. But when compiling tests I get
cthehardway/dlib/tests/list_tests.c:36: undefined reference to `List_pop'
Here is my Makefile:
CFLAGS=-g -O2 -Wall -Wextra -Isrc -rdynamic -DNDEBUG $(OPTFLAGS)
LIBS=-ldl $(OPTLIBS)
PREFIX?=/usr/local
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TEST_SRC=$(wildcard tests/*_tests.c)
TESTS=$(patsubst %.c,%,$(TEST_SRC))
TARGET=build/libd.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target Build
all: $(TARGET) $(SO_TARGET) tests
dev: CFLAGS=-g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build:
#mkdir -p build
#mkdir -p bin
# The Unit Tests
.PHONY: tests
tests: CFLAGS += $(TARGET)
tests: $(TESTS)
sh ./tests/runtests.sh
# The Cleaner
clean:
rm -rf build $(OBJECTS) $(TESTS)
rm -f tests/tests.log
find . -name "*.gc*" -exec rm {} \;
rm -rf `find . -name "*.dSYM" -print`
# The Install
install: all
install -d $(DESTDIR)/$(PREFIX)/lib/
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
# The Checker
check:
#echo Files with potentially dangerous functions.
#egrep '[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)\
|stpn?cpy|a?sn?printf|byte_)' $(SOURCES) || true
And here is the link to the project itself (it is small, couple of files);
The project is dlib folder, disregard outside files.
Only the tests target fails. The library builds fine.
https://github.com/Voley/cthehardway
You're not including your library in the link of the test.
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
You should include $(TARGET) in the bottom line.
At least, I think that's the case. It's a dependency, so I assume you want to link with it.