0

I've been working on a Makefile but having two issues. The application directory contains autotools files for a Yocto build but for development I'd like to do both x86 & ARM builds locally via Makefile.

The project has the following directory structure (edited down for clarity):

├── autogen.sh
├── build
├── configure.ac
├── COPYING
├── database_dump
├── external
│   ├── Makefile.am
│   ├── sqlite3
│   │   ├── sqlite3.c
│   │   ├── sqlite3ext.h
│   │   └── sqlite3.h
│   └── sqlite3pp
│       ├── headeronly_src
│       │   ├── sqlite3ppext.h
│       │   ├── sqlite3ppext.ipp
│       │   ├── sqlite3pp.h
│       │   └── sqlite3pp.ipp
│       ├── README.md
│       ├── src
│       │   ├── sqlite3pp.cpp
│       │   ├── sqlite3ppext.cpp
│       │   ├── sqlite3ppext.h
│       │   └── sqlite3pp.h
│       └── test
│           ├── testaggregate.cpp
│           └── testselect.cpp
├── LICENSE
├── m4
│   ├── ax_cxx_compile_stdcxx.m4
│   └── ax_pthread.m4
├── Makefile.am
├── README.md
├── scripts
│   └── Makefile
├── src
│   ├── database.cpp
│   ├── database.h
│   ├── errorMsgs.h
│   ├── languages.h
│   ├── log.h
│   ├── main.cpp
│   ├── mainWindow.cpp
│   ├── mainWindow.h
│   └──pages.cpp

As you can see my Makefile is in /scripts. I'd like to keep it here to prevent conflicting with the autotools build.

Edit: I realise its strange to use both Autotools & Makefile but there is a method to my madness:

  1. Autotools used by Yocto to build the application in an image
  2. Use Makefile to make quick standalone compilations for both x86 & ARM (the application runs on both architectures).

The Makefile is currently:

TARGETS := applicationName
BUILD_DIR := ../build
SRC_DIR := ../src
CXXFLAGS :=-std=c++14 $(shell pkg-config --cflags --libs)
LDFLAGS :=$(shell pkg-config --cflags --libs) -lgpiod -pthread -lsqlite3

# Tried adding directory using vpath:
# vpath %.h ../external/sqlite3pp/headeronly_src/

SRCS := $(shell find $(SRC_DIR) -name *.cpp -or -name *.c -or -name *.s)
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
DEPS := $(OBJS:.o=.d)

INC_DIRS := $(shell find $(SRC_DIR) -type d)
INC_DIRS := $(INC_DIRS) ./external/sqlite3pp/headeronly_src/
INC_FLAGS := $(addprefix -I,$(INC_DIRS))

#echo $(INC_FLAGS)

CPPFLAGS :=$(INC_FLAGS) -MMD -MP

$(BUILD_DIR)/$(TARGETS): $(OBJS)
    $(CC) $(OBJS) -o $@ $(LDFLAGS)

# assembly
$(BUILD_DIR)/%.s.o: %.s
    mkdir -p $(dir $@)
    $(AS) $(ASFLAGS) -c $< -o $@

# c source
$(BUILD_DIR)/%.c.o: %.c
    mkdir -p $(dir $@)
    $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@

# cpp source
$(BUILD_DIR)/%.cpp.o: %.cpp
    mkdir -p $(dir $@)
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

.PHONY: clean
clean:
    rm $(SRC_DIR)/*.o
    rm $(SRC_DIR)/*.d

-include $(DEPS)

The issues when I try running make:

  1. The build files end up in /src instead of /build
  2. I get the error:
username@username-XPS:~/Projects/sama5d4/applicationName/scripts$ make
mkdir -p ../build/../src/
g++ -I../src -I../external/sqlite3pp/headeronly_src/ -MMD -MP -std=c++14 -pthread -I/usr/local/include -I/usr/include/gstreamer-1.0 -I/usr/include/orc-0.4 -I/usr/include/gstreamer-1.0 -I/usr/include/lua5.3 -I/usr/include/plplot -I/usr/include/x86_64-linux-gnu -I/usr/include/librsvg-2.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 -I/usr/include/libpng16 -L/usr/local/lib -legt -lcairo -c ../src/dosingBoards.cpp -o ../build/../src/dosingBoards.cpp.o
mkdir -p ../build/../src/
g++ -I../src -I../external/sqlite3pp/headeronly_src/ -MMD -MP -std=c++14 -pthread -I/usr/local/include -I/usr/include/gstreamer-1.0 -I/usr/include/orc-0.4 -I/usr/include/gstreamer-1.0 -I/usr/include/lua5.3 -I/usr/include/plplot -I/usr/include/x86_64-linux-gnu -I/usr/include/librsvg-2.0 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/uuid -I/usr/include/freetype2 -I/usr/include/libpng16 -L/usr/local/lib -legt -lcairo -c ../src/main.cpp -o ../build/../src/main.cpp.o
In file included from ../src/mainWindow.h:18,
                 from ../src/main.cpp:1:
../src/database.h:14:10: fatal error: external/sqlite3pp/headeronly_src/sqlite3pp.h: No such file or directory
   14 | #include "external/sqlite3pp/headeronly_src/sqlite3pp.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:36: ../build/../src/main.cpp.o] Error 1

As you can see I tried amending the include directory (a number of variations) & using vpath but no success.

Could anyone please provide some pointers?

Thanks,

leo8382
  • 91
  • 8
  • Why in the world would you write your own makefile by hand when you have an Autotools build system Right. There. that can make appropriate ones for you? – John Bollinger May 13 '22 at 00:56
  • There are some glaring errors in that makefile, but first, what is your working directory (the one you're in when you execute Make)?) – Beta May 13 '22 at 04:36
  • Added an edit to enpand on reason for Autotools & Makefile: I realise its strange to use both Autotools & Makefile but there is a method to my madness: 1. Autotools used by Yocto to build the application in an image 2. Use Makefile to make quick standalone compilations for both x86 & ARM (the application runs on both architectures). – leo8382 May 13 '22 at 09:05
  • I execute make from /scripts – leo8382 May 13 '22 at 09:06
  • It is much more useful to look at the actual commands ran by make than to look at the makefile and try to reconstruct them in your head. – n. m. could be an AI May 13 '22 at 09:41
  • Thanks for looking. I've added the full terminal output – leo8382 May 13 '22 at 10:00
  • I'm still not seeing the point. So what if Yocto is using the Autotooling? When Yocto uses autotooling, it is typically by leveraging projects' *general purpose* autotooling to serve its needs. That Yocto is using it is not directly relevant to whether you can also use it for your own purposes. Is there something about the autotooling itself that makes it unsuitable? – John Bollinger May 13 '22 at 15:52
  • You need to add either `../` or the absolute path of the project root to the include path, because that's what `external/sqlite3pp/headeronly_src/sqlite3pp.h` is relative to. – n. m. could be an AI May 13 '22 at 16:05
  • @JohnBollinger Ok, if I want to use autotools to produce simultaneous & independent x86 & ARM standalone local builds (leveraging the Yocto SDK) how do I go about that? It seems a lot simpler to accomplish this requirement using Makefile (I currenlt just use a bash script) – leo8382 May 13 '22 at 19:27
  • @leo8382, autotools build systems provide support for both out of source (vpath) builds and cross builds, including in combination. For example, `mkdir x86_build; cd x86_build'; ../configure [options]; make`. If you need to run `autogen.sh` or `autoreconf` first then that should only need to be once for all builds. – John Bollinger May 13 '22 at 19:41
  • @JohnBollinger Thanks for the suggestion. To clarify you mean that autotools can populate two sud-directories with different makefiles without modifying the contents of the Makefile.am, configure.ac or autogen.sh in the parent directory? – leo8382 May 13 '22 at 20:07
  • Yes, @leo8382, I mean exactly that. Moreover, the build directories can be anywhere on the system. When you run `configure`, by whatever path you use, your current working directory is configured as a build directory. All makefiles and other outputs produced by `configure` are written there, and when you subsequently build there, that's where the build results will go, too. This is standard Autotools behavior. – John Bollinger May 13 '22 at 23:59
  • Full disclosure: it is possible for individual projects to break the resulting vpath builds, so this is not guaranteed to work. But that is easy to test. It is well worth that minor effort just for the possibility of saving yourself all the effort and trouble of maintaining an altogether separate build system. – John Bollinger May 14 '22 at 00:03

1 Answers1

0

I solved this by including the project directory as absolute, eg.

THIS_DIRS :=/home/me/Projects/sama5d4/thisProject

I think using the make $(CURDIR) might work as well, something like:

THIS_DIRS :=.../$(CURDIR)

But I haven't tested this solution.

The compilation is then:

%.cpp.o: %.cpp
    mkdir -p ${BUILD_DIR}
    echo "Building cpp source" $<
    $(CXX) $(CFLAGS) $(CXXFLAGS) -I$(THIS_DIRS) -c $< -o $@ 
leo8382
  • 91
  • 8