Makefile related

Hello,

I am trying to improve my makefile and development environment. Currently I have the below structure

/*
rifo@rifo:~/projects/agi/toradex/$ tree
.
├── hello3
├── inc
│   ├── json.h
│   └── post.h
├── makefile
└── src
    ├── json.c
    ├── main.c
    └── post.c
*/

For the above structure, I use the below makefile and everything turns out fine. (Note that I use #include “…/inc/post.h” “…/inc/json.h” in my source files)

SYSROOTS ?= /usr/local/oecore-x86_64/sysroots
CC = ${SYSROOTS}/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi/arm-angstrom-linux-gnueabi-gcc
INCLUDES = -I${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include
LIB_PATH = -L${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi/lib
LIBS = -lpthread -lcurl -ljansson
CFLAGS = -O0 -g -Wall -std=gnu99 -mfloat-abi=hard --sysroot=${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi


all: $(TARGET)
	${CC} ${CFLAGS} ${INCLUDES} ${LIB_PATH} ${LIBS} src/json.c src/post.c src/main.c -o hello3

clean:
	rm -rf hello3 

Now I want to have an extra folder called “obj” where I can place the object files. In my makefile, I want to first compile every source file and then link it at the end.

/*
rifo@rifo:~/projects/agi/toradex/$ tree
.
├── hello3
├── inc
│   ├── json.h
│   └── post.h
├── makefile
├── obj
│   ├── json.o
│   ├── main.o
│   └── post.o
└── src
    ├── json.c
    ├── main.c
    └── post.c
*/

For this structure, I tried the below makefile but can’t get it working. Can you please guide me for solving this problem?

SYSROOTS ?= /usr/local/oecore-x86_64/sysroots
CC = ${SYSROOTS}/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi/arm-angstrom-linux-gnueabi-gcc
INCLUDES = -I${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include -I./inc
LIB_PATH = -L${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi/lib
LIBS = -lpthread -lcurl -ljansson
CFLAGS = -O0 -g -Wall -std=gnu99 -mfloat-abi=hard --sysroot=${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi
CPP_FILES = $(wildcard src/*.c)
OBJ_FILES = $(addprefix obj/, $(notdir $(CPP_FILES:.c=.o)))
TARGET = json_post

all: $(TARGET)

$(TARGET): $(OBJ_FILES)
	$(CC) -o $(TARGET) ${LIB_PATH} $(LIBS) $^ 

obj/%.o: src/%.c $(DEPS)
	$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<


clean:
	rm ./${TARGET} obj/*.o 

I have used a very similar make file for compiling the same project on Beaglebone Black (no cross compiling) so in theory I expected this to work however I got the below errors

/*
rifo@rifo:~/projects/agi/toradex/$ make
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi/arm-angstrom-linux-gnueabi-gcc -O0 -g -Wall -std=gnu99 -mfloat-abi=hard --sysroot=/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi -I/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include -I./inc -c -o obj/post.o src/post.c
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi/arm-angstrom-linux-gnueabi-gcc -O0 -g -Wall -std=gnu99 -mfloat-abi=hard --sysroot=/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi -I/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include -I./inc -c -o obj/main.o src/main.c
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi/arm-angstrom-linux-gnueabi-gcc -O0 -g -Wall -std=gnu99 -mfloat-abi=hard --sysroot=/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi -I/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include -I./inc -c -o obj/json.o src/json.c
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi/arm-angstrom-linux-gnueabi-gcc -o json_post -L/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/lib -lpthread -lcurl -ljansson obj/post.o obj/main.o obj/json.o 
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot open crt1.o: No such file or directory
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot open crti.o: No such file or directory
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot open crtbegin.o: No such file or directory
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot open crtend.o: No such file or directory
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot open crtn.o: No such file or directory
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -lpthread
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -lcurl
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -ljansson
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -lgcc
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -lgcc
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -lc
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -lgcc
/usr/local/oecore-x86_64/sysroots/x86_64-angstromsdk-linux/usr/libexec/arm-angstrom-linux-gnueabi/gcc/arm-angstrom-linux-gnueabi/5.2.1/real-ld: error: cannot find -lgcc
src/post.c:30: error: undefined reference to 'curl_slist_append'
src/post.c:31: error: undefined reference to 'curl_slist_append'
src/post.c:33: error: undefined reference to 'curl_easy_init'
src/post.c:41: error: undefined reference to 'curl_easy_setopt'
src/post.c:42: error: undefined reference to 'curl_easy_setopt'
src/post.c:43: error: undefined reference to 'curl_easy_setopt'
src/post.c:46: error: undefined reference to 'curl_easy_setopt'
src/post.c:51: error: undefined reference to 'strlen'
src/post.c:54: error: undefined reference to 'curl_easy_perform'
src/post.c:58: error: undefined reference to 'stderr'
src/post.c:58: error: undefined reference to 'stderr'
src/post.c:58: error: undefined reference to 'curl_easy_strerror'
src/post.c:58: error: undefined reference to 'fprintf'
src/post.c:65: error: undefined reference to 'curl_easy_cleanup'
src/post.c:69: error: undefined reference to 'puts'
src/post.c:79: error: undefined reference to 'curl_global_cleanup'
/usr/local/oecore-x86_64/sysroots/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include/jansson.h:112: error: undefined reference to 'json_delete'
src/main.c:37: error: undefined reference to 'puts'
src/main.c:39: error: undefined reference to 'json_dumps'
src/main.c:40: error: undefined reference to 'puts'
src/main.c:43: error: undefined reference to 'free'
src/main.c:44: error: undefined reference to 'sleep'
src/main.c:62: error: undefined reference to 'curl_global_init'
src/main.c:64: error: undefined reference to 'pthread_create'
src/main.c:66: error: undefined reference to 'pthread_join'
src/json.c:19: error: undefined reference to 'json_pack'
collect2: error: ld returned 1 exit status
makefile:14: recipe for target 'json_post' failed
make: *** [json_post] Error 1

*/

thanks a lot for your help
rifo

Hi

Hard to tell without trying it out.

I see several things which I would look into:

  • The LIB_PATH setting is probably unneeded at all, at least if you pass a proper sysroot to the linker. Additonally you would also need to add -L…/usr/lib if to specify most of the library locations.
  • I usually pass CFLAGS to the linker also. That would pass the sysroot to the linker, additionally the linker needs to know that you build for hardfloat to choose the right libraries.
  • At least when linking static libraries they need to be added after the object files on the linker command line. Maybe you get away with it when linking shared object files. e.g. swap ‘$(LIBS) $^’ to ‘$^ $(LIBS)’
  • Note that when you source the SDK environment script you actually get e.g. CC, CXX … set. Check e.g. echo $CC. So not setting CC in your Makefile and remove the cross flags from CFLAGS would allow for a more generic Makefile which likely would also build an X86 binary for your buildhost.

Max

thanks a lot!
passing CFLAGS to the linker did the trick. I guess the main problem was that I didn’t pass a proper sysroot to the linker. Below is the working makefile

/*
SYSROOTS ?= /usr/local/oecore-x86_64/sysroots
CC = ${SYSROOTS}/x86_64-angstromsdk-linux/usr/bin/arm-angstrom-linux-gnueabi/arm-angstrom-linux-gnueabi-gcc
INCLUDES = -I${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi/usr/include -I./inc
LIB_PATH = -L${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi/usr/lib
LIBS = -lpthread -lcurl -ljansson
CFLAGS = -O0 -g -Wall -std=gnu99 -mfloat-abi=hard --sysroot=${SYSROOTS}/armv7at2hf-neon-angstrom-linux-gnueabi
CPP_FILES = $(wildcard src/*.c)
OBJ_FILES = $(addprefix obj/, $(notdir $(CPP_FILES:.c=.o)))
TARGET = json_post

all: $(TARGET)

$(TARGET): $(OBJ_FILES)
	$(CC) -o $(TARGET) $(CFLAGS) ${LIB_PATH} $^ $(LIBS)

obj/%.o: src/%.c $(DEPS)
	$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<


clean:
	rm ./${TARGET} obj/*.o 

*/