Convert micropython makefile to cmakelist.txt - c

I am trying to convert micropython makefile to cmakelists.txt from https://docs.micropython.org/en/latest/develop/porting.html
# Include the core environment definitions; this will set $(TOP).
include ../../py/mkenv.mk
# Include py core make definitions.
include $(TOP)/py/py.mk
# Set CFLAGS and libraries.
CFLAGS = -I. -I$(BUILD) -I$(TOP)
LIBS = -lm
CROSS_COMPILE ?= arm-none-eabi-
# Define the required source files.
SRC_C = \
main.c \
mphalport.c \
lib/mp-readline/readline.c \
lib/utils/gchelper_generic.c \
lib/utils/pyexec.c \
lib/utils/stdout_helpers.c \
# Define the required object files.
OBJ = $(PY_CORE_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
# Define the top-level target, the main firmware.
all: $(BUILD)/firmware.elf
# Define how to build the firmware.
$(BUILD)/firmware.elf: $(OBJ)
$(ECHO) "LINK $#"
$(Q)$(CC) $(LDFLAGS) -o $# $^ $(LIBS)
$(Q)$(SIZE) $#
# Include remaining core make rules.
include $(TOP)/py/mkrules.mk
Current progress on cmakelists.txt
cmake_minimum_required(VERSION 3.17)
set(CMAKE_CXX_STANDARD 14)
set(MICROPY_TARGET firmware)
set(MICROPY_DIR "../..")
set(MICROPY_PORT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
include(${MICROPY_DIR}/py/py.cmake)
project(${MICROPY_TARGET})
set(MICROPY_SOURCE_PORT
${MICROPY_PORT_DIR}/main.c
${MICROPY_PORT_DIR}/mphalport.c
${MICROPY_DIR}/lib/mp-readline/readline.c
${MICROPY_DIR}/lib/utils/gchelper_generic.c
${MICROPY_DIR}/lib/utils/pyexec.c
${MICROPY_DIR}/lib/utils/stdout_helpers.c
)
target_sources(app PRIVATE
${MICROPY_SOURCE_PY}
${MICROPY_SOURCE_PORT}
)
target_link_libraries(app PRIVATE ${MICROPY_TARGET})
include(${MICROPY_DIR}/py/mkrules.cmake)
I am getting error while running:
CMake error at line 33 :
can't specify sources for target "app" which is not built by this project.
I am taking help from this: https://github.com/micropython/micropython/blob/master/ports/zephyr/CMakeLists.txt , but I think I am missing some steps.

Related

How to generate dependency files when generating object files of c sources with make

I am implementing a build system using the GNU tools, GCC and make to compile multiple targets, link them together and create a final executable. All these support two platforms; the host environment and the embedded system MSP432.
I am taking an introductory course on embedded systems and doing an assignment that I am fighting with some days ago. I was trying by myself reading over the internet, also reading here in stackoverflow but I don’t get it yet, I am still a rookie on this, so I hope someone can explain me or giving me a hint about how to fix the issue
As said, the build system must support the two platforms so at first step, I focus on making sure all works for the host environment.
In the makefile I have created rules for the following targets:
build - Generates executable file, object files, dependency files and map file
%.o: %.c ... - Generates object files and its dependencies
compile-all - Compiles all objects but do not link them
%.i: %.c - Generates preprocessed output of C source files
%.asm: %.C - Generates assembly output of C source files
clean - Clean all generated files
The issue is when executing make build PLATFORM=HOST
Running the command, we get:
.../src$ sudo make build PLATFORM=HOST
gcc -Wall -Werror -g -std=c99 -DHOST -Wl,-O0,-Map=c1m2.map main.c memory.c -I../includes/common -o c1m2.out
make: *** No rule to make target 'main.o', needed by 'build'. Stop.
I notice that the error comes because the line 132 were we have
%.o: %.c
This line is intended for disabling the built-in rule and using the user defined one that comes next line, but it is not doing it, so I try commenting this line and executing the build again and we get:
.../src$ sudo make build PLATFORM=HOST
gcc -Wall -Werror -g -std=c99 -DHOST -Wl,-O0,-Map=c1m2.map main.c memory.c -I../includes/common -o c1m2.out
gcc -Wall -Werror -g -std=c99 -DHOST -E -c -o main.o main.c
main.c:23:22: fatal error: platform.h: No such file or directory
compilation terminated.
< builtin >: recipe for target 'main.o' failed
make: *** [main.o] Error 1
Now it says that it does not find “platform.h” despite it being indicated by the INCLUDES variable that contains the location of the header file. Also, it is using the built-in recipe for generating the object files and fails.
So I am stuck at this point, the idea is building the output executable, the map file, the object files and its dependencies files when executing “make build PLATFORM=HOST”.
At the beginning I wrote the build target just for generating the output, the map and object files and did work and then after doing the modifications for generating the dependency files I got lost with this error.
The other recipes for generating preproceessed files, assembly files and doing a clean were working ok.
You can clone the folder with all the needed files from: https://github.com/Fornaso/C1M2.git
Thank you all in advance.
Here is my Makefile:
#******************************************************************************
# Copyright (C) 2017 by Alex Fosdick - University of Colorado
#
# Redistribution, modification or use of this software in source or binary
# forms is permitted as long as the files maintain this copyright. Users are
# permitted to modify this and use it to learn about the field of embedded
# software. Alex Fosdick and the University of Colorado are not liable for any
# misuse of this material.
#
#******************************************************************************
# Modified on April 2020 by Adrián Fornaso
#------------------------------------------------------------------------------
# Simple Makefile for multitarget build system
#
# Use: make [TARGET] [PLATFORM-OVERRIDES]
#
# Build Targets:
#
# build - Builds and links all source files and genereates:
#
# c1m2.map - Map file for the full build
# *.d - Dependency Files for each source file
# *.o - Individual object files
# c1m2.out - Output Executable file
#
#<FILE>.i - Builds <FILE>.i preprocessed file.
#<FILE>.asm - Builds <FILE>.i assembly file.
#<FILE>.o - Builds <FILE>.o object file.
#compile-all - Compile all objects but do NOT link them.
#clean - Removes all generated files.
#
# Platform Overrides: Conditionally assign the appropriate compiler flags,
# linker flags, and architecture flags. The target platform
# must be provided at the command line with the make
# command to set the platform you are compiling for.
#
# PLATFORM = MSP432 - The target embedded system will use
# the cross compiler, arm-none-eabi-gcc.
# PLATFORM = HOST - The host embedded system will use the
# native compiler, gcc.
#
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#General Flags (Both Platforms)
#
# -Wall Enable All Warning Messages (CFLAGS)
# -Werror Treats All Warnings as Errors(CFLAGS)
# -g Generate Debugging Info in Executable (CFLAGS)
# -O0 The level of optimization (-O0, -O1, -O2, -O3)) (LDFLAGS)
# -std=c99 The C standard set (CFLAGS)
#
#------------------------------------------------------------------------------
#Target name
BASENAME = c1m2
TARGET = $(BASENAME).out
#General Flags
COMMONCFLAGS = -Wall -Werror -g -std=c99
COMMONLDFLAGS = -Wl,-O0,-Map=$(BASENAME).map
#No spaces after commas after -Wl option.
CPPFLAGS = -E
# -E flag makes the compiler stop in the preprocessed output
#Compile time switches
ifeq ($(PLATFORM), MSP432)
INCLUDES = -I../includes/common \
-I../includes/msp432 \
-I../includes/CMSIS
SOURCES = main.c \
memory.c \
interrupts_msp432p401r_gcc.c \
startup_msp432p401r_gcc.c \
system_msp432p401r.c
LINKER_FILE = msp432p401r.lds
CPU = cortex-m4
ARCH = armv7e-m
SPECS = nosys.specs
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
LDFLAGS = $(COMMONLDFLAGS), -T=$(LINKER_FILE)
CFLAGS = $(COMMONCFLAGS) -D$(PLATFORM) -mcpu=$(CPU) \
-march=$(ARCH) --specs=$(SPECS)
OBJDUMP = arm-none-eabi-objdump
endif
ifeq ($(PLATFORM), HOST)
INCLUDES = -I../includes/common
SOURCES = main.c \
memory.c
CC = gcc
LD = ld
LDFLAGS = $(COMMONLDFLAGS)
CFLAGS = $(COMMONCFLAGS) -D$(PLATFORM)
OBJDUMP = objdump
endif
#Listing object files:
OBJECTS = $(SOURCES:.c=.o)
# 1. --------------------------------------------------------------------------
# Complete build: c1m2.map - Map file for the full build
# *.d - Dependency Files for each source file
# *.o - Individual object files
# c1m2.out - Output Executable file
# LDFLAGS contains the flags for creating the *.map file
.PHONY: build
build: $(TARGET) $(OBJECTS)
$(TARGET):
$(CC) $(CFLAGS) $(LDFLAGS) $(SOURCES) $(INCLUDES) -o $#
# 2. --------------------------------------------------------------------------
# //// Generates the object files of all c-program implementation files and its
# dependecies. ///////////////////////////////////////////////////////////
#This implementation places dependency files into a subdirectory named .deps.
DEPDIR := .deps
DEPFLAGS = -MT $# -MD -MP -MF $(DEPDIR)/$*.d
# Delete the built-in rules for building object files from .c files, so that
# our rule is used instead.
#%.o: %.c
# Our rule for building object files with its dependency
%.o: %.c $(DEPDIR)/%.d | $(DEPDIR)
$(CC) $(DEPFLAGS) -c $(CFLAGS) $(INCLUDES) -o $# $^
# Declare a rule for creating the dependency directory if it doesn’t exist.
$(DEPDIR): ; #mkdir -p $#
# Generate a list of all the dependency files that could exist.
DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d)
# Mention each dependency file as a target, so that make won’t fail if the file
# doesn’t exist.
$(DEPFILES):
# 2 bis. ----------------------------------------------------------------------
# /// Generates the object file of all c-program implementation files. ////////
#%.o: %.c
# $(CC) -c $(CFLAGS) $(INCLUDES) -o $# $^
# 3. --------------------------------------------------------------------------
# /// Compile all objects but do NOT link them. ///////////////////////////////
.PHONY: compile-all
compile-all: $(SOURCES)
$(CC) -c $(CFLAGS) $(INCLUDES) $^
# 4. --------------------------------------------------------------------------
# /// Generates the preprocessed output of all c-program implementation files.
%.i: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -o $# $^
# 5. --------------------------------------------------------------------------
# /// Create assembler file of a C source. ////////////////////////////////////
%.asm: %.c
$(CC) -S $(CFLAGS) $(INCLUDES) $< -o $#
# -S flag tells the compiler just generate the assembly file
# 6. --------------------------------------------------------------------------
# /// Removes all compiled objects, preprocessed outputs, assembly outputs,
# executable files and build output files. ////////////////////////////////
.PHONY: clean
clean:
rm -f $(OBJECTS) $(TARGET) $(BASENAME).map *.asm *.i
rm -r .dep
#End of file
There are two small mistakes which took me quite a while to see:
DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d) has to be DEPFILES := $(SOURCES:%.c=$(DEPDIR)/%.d) - otherwise DEPFILES is empty since SRCS is undefined.
In $(CC) $(DEPFLAGS) -c $(CFLAGS) $(INCLUDES) -o $# $^ the $^ (all the prerequisites) expands to e. g. main.c .deps/main.d, so a not yet existing .deps/main.d is passed as an input file; we want $*.c instead of $^.
Another minor error is:
rm -r .dep should be rm -r .deps or rm -r $(DEPDIR).

Qt static lib submodule build

I want to automate building thirdparty libraries and include them in my Qt project.
The .pro file of my Qt project looks like this:
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
QMAKE_EXTRA_TARGETS += stalib
PRE_TARGETDEPS += stalib
stalib.commands = make ../thirdparty/stalib/Makefile
LIBS += -L$${PWD}/../thirdparty/stalib/lib -lStalib
INCLUDEPATH += $${PWD}/../thirdparty/stalib/src
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp
The Makefile of my thirdparty depedency submodule looks like this:
#-----------------------------------------------#
# Makefile for hello world #
#-----------------------------------------------#
# add preprocessor define
DEF_PARAMS = -DGREET=\"world\"
# Just to make sure
ifndef CROSS_COMPILE
$(error "cross-compilation environment not activated properly")
endif
# add debug symbols, DO NOT overwrite contents of FLAGS, append!
CFLAGS += -g $(DEF_PARAMS)
#Compilation only ignore warnings (ignore/-w, show all/-Wall).
CFLAGS += -c -w
SOURCEDIR=./src
LIBDIR=./lib
#-----------------------------------------------#
# Project Specific Settings #
#-----------------------------------------------#
# include directories relative to $SDKTARGETSYSROOT/usr/include (system HEADERS) or this Makefile (project headers).
INC_PARAMS = $(SOURCEDIR)
# project headers
HEADERS = $(SOURCEDIR)/math.h
# project sources
SOURCES = $(SOURCEDIR)/math.c
# Object files.
OBJECTS=$(SOURCES:%.c=%.c.o)
# Link libraries
# Libraries search directories relative to $SDKTARGETSYSROOT/usr/libs
# Library name without lib and .so e.g. libm.so -> -lm.
LINK_LIBS=
#Target name
TARGET_STATIC = $(LIBDIR)/libStalib.a
#-----------------------------------------------#
# Print Make Parameters #
#-----------------------------------------------#
print-%:
#echo "SOURCES=$(SOURCES)"
#echo "HEADERS=$(HEADERS)"
#echo "DEF_PARAMS=$(DEF_PARAMS)"
#echo "CFLAGS=$(CFLAGS)"
#echo "LDFLAGS=$(LDLAGS)"
#echo $* = $($*)
#-----------------------------------------------#
# Makefile Make Executable #
#-----------------------------------------------#
.SUFFIXES: .c
#Build rules begin.
all: $(TARGET_STATIC)
#Build rule for static library target.
$(TARGET_STATIC): $(OBJECTS)
$(AR) rc $# $(OBJECTS)
#Build rule for dynamic library target.
$(TARGET_SHARED): $(OBJECTS)
$(LD) $(LDFLAGS) $(OBJECTS) $(LINK_LIBS) -o $#
#Build rule for executeable target
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $^ $(LINK_LIBS) -o $#
#Compilation rule for c files.
%.c.o: %.c $(HEADERS)
$(CC) $(CFLAGS) $(INC_PARAMS) $< -o $#
#Clean-up object files and target.
clean:
rm -f $(OBJECTS) $(TARGET) $(TARGET_STATIC) $(TARGET_SHARED)
However I get a linker error when building. It can not find the function defined in the math.h file:
#ifndef MATHH
#define MATHH
int addNums(int a, int b);
#endif
But the strange thing is that QtCreator is able to follow the reference to the header file.
For all of you who want to check the sources directly, or fiddle around with them:
https://github.com/faxe1008/myapp
https://github.com/faxe1008/stalib
Any help or suggestions on how to improve are appreciated.
If you want to build the library automatically, then you need to modify this line in your .pro:
stalib.commands = make -C../thirdparty/stalib CROSS_COMPILE=1
But that is not your question. You don't show your .cpp code, but I guess that you forgot to surround your #include like this:
extern "C" {
#include "math.h"
}
You can't include non system C headers in C++ sources without that. See: https://isocpp.org/wiki/faq/mixing-c-and-cpp

Make C and ASM files in the same makefile fails

I have written a Makefile to generate a kernel image from both ASM and C sources however it fails to compile the C sources. I think the error is in using two object lists one for ASM and one for C. If there are other issues with the file please feel free to tell me.
Terminal Output
arm-none-eabi-as -I source/ source/maths.s -o build/maths.o
arm-none-eabi-as -I source/ source/tags.s -o build/tags.o
make: *** No rule to make target 'build/firstCFile.o', needed by 'build/output.elf'. Stop.
Makefile
# The toolchain to use. arm-none-eabi works, but there does exist
# arm-bcm2708-linux-gnueabi.
ARMGNU ?= arm-none-eabi
# The intermediate directory for compiled object files.
BUILD = build/
# The directory in which source files are stored.
SOURCE = source/
# The name of the output file to generate.
TARGET = bin/kernel.img
# The name of the assembler listing file to generate.
LIST = bin/kernel.list
# The name of the map file to generate.
MAP = bin/kernel.map
# The name of the linker script to use.
LINKER = kernel.ld
# The names of libraries to use.
LIBRARIES := csud
# The names of all object files that must be generated. Deduced from the
# assembly code files in source.
OBJECTS := $(patsubst $(SOURCE)%.s,$(BUILD)%.o,$(wildcard $(SOURCE)*.s))
OBJECTS2 := $(patsubst $(SOURCE)%.c,$(BUILD)%.o,$(wildcard $(SOURCE)*.c))
# Rule to make everything.
all: $(TARGET) $(LIST)
# Rule to remake everything. Does not include clean.
rebuild: all
# Rule to make the listing file.
$(LIST) : $(BUILD)output.elf
$(ARMGNU)-objdump -d $(BUILD)output.elf > $(LIST)
# Rule to make the image file.
$(TARGET) : $(BUILD)output.elf
$(ARMGNU)-objcopy $(BUILD)output.elf -O binary $(TARGET)
# Rule to make the elf file.
$(BUILD)output.elf : $(OBJECTS) $(OBJECTS2) $(LINKER)
$(ARMGNU)-ld --no-undefined $(OBJECTS) $(OBJECTS2) -L. $(patsubst %,-l %,$(LIBRARIES)) -Map $(MAP) -o $(BUILD)output.elf -T $(LINKER)
# Rule to make the object files.
$(BUILD)%.o: $(SOURCE)%.s
$(ARMGNU)-as -I $(SOURCE) $< -o $#
$(BUILD):
mkdir $#
I think you need a rule to make from the c source:
$(BUILD)%.o : $(SOURCE)%.c
$(ARMGNU)-gcc -c -I $(SOURCE) $< -o $#

issues with Makefile in C

#----------------------------------------------------------------------- ------
# Choose a compiler & its options
#--------------------------------------------------------------------------
CC = gcc
OPTS = -W -O3
#--------------------------------------------------------------------------
# Add the debug flag to compile for use by a debugger
#--------------------------------------------------------------------------
#DEBUG=-g
#--------------------------------------------------------------------------
# Add the names of the directories
#--------------------------------------------------------------------------
SRCDIR= src
OBJDIR= obj
INCDIR= include
BINDIR= bin
#--------------------------------------------------------------------
# Add the rest of the source files. Don't forget to add the '\' character
# to continue the line. You don't need it after the last source file
#--------------------------------------------------------------------
SRCS=$(SRCDIR)/Lab12.c \ Function1.c \ Function2.c \ Function3.c \ Function4.c \ Function5.c
#--------------------------------------------------------------------
# You don't need to edit the next few lines. They define other flags
# used in the compilation of the source code
#--------------------------------------------------------------------
INCLUDE = $(addprefix -I,$(INCDIR))
OBJS=${SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o}
CFLAGS = $(OPTS) $(INCLUDE) $(DEBUG)
#--------------------------------------------------------------------
# Add the name of the executable after the $(BINDIR)/
#--------------------------------------------------------------------
TARGET = $(BINDIR)/ Lab12
all: $(TARGET)
$(TARGET): $(OBJS)
${CC} ${CFLAGS} -o $# $(OBJS)
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm -f $(OBJS)
cleanall:
rm -f $(OBJS)
rm -f Lab12
#--------------------------------------------------------------------
# Add a target named cleanall that will remove the object files as well
# as the executable
#--------------------------------------------------------------------
I have all my "header" files in the include folder. I have all my source code in the src folder (Lab12.c , Function1.c, Function2.c ...). I keep getting this error when i use the make command.
Makefile:45: target Function1.c' doesn't match the target pattern
Makefile:45: target Function2.c' doesn't match the target pattern
Makefile:45: target Function3.c' doesn't match the target pattern
Makefile:45: target Function4.c' doesn't match the target pattern
Makefile:45: target ` Function5.c' doesn't match the target pattern
gcc -W -O3 -Iinclude -c -o Function1.c
gcc: no input files
make: *** [ Function1.c] Error 1
I cant quite figure out why it is behaving this way. All these files are in the src code folder so why isnt the system recognizing them?
SRCS=$(SRCDIR)/Lab12.c \ Function1.c \ Function2.c \ Function3.c \
seems wrong; you should try
SRCS=$(SRCDIR)/Lab12.c Function1.c Function2.c Function3.c
instead
UPDATE
If Function1.c and so on are in ´$(SRCDIR)`, you must prepend the directory to these files, too. (comment from M Oehm)

Makefile recursive not passing CPPFLAGS

First of all, sorry if I end up making a too long post, but I think it would be missing information otherwise.
I'd like to include my repository version in each build.
There is a main makefile that masters some other ones in their respective subdirectories.
The subprojects are "automaked".
I am trying to pass a variable containing the svnversion to inner Makefiles like this:
# Main Makefile
SUBDIRS = sd1 sd2
REPO_VERSION = `svnversion`
export ECHO = #echo
export CPPFLAGS
all: versioned
$(ECHO) "Build of all projects in $(PWD) finished."
clean :
$(ECHO) "Cleaning up entire project tree..."
-for d in $(SUBDIRS); do ($(ECHO) "Cleaning up \"$$d\""; $(MAKE) -C $$d clean ); done
.PHONY: versioned unversioned $(SUBDIRS)
versioned: CPPFLAGS = -DREPO_VERSION=\"v$(REPO_VERSION)\"
versioned: subdirs
unversioned: subdirs
versioned unversioned:
$(ECHO) "Build $# finished."
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(ECHO) "== Building $# =="
$(ECHO) " [ CPPFLAGS = \"$(CPPFLAGS)\" ]"
( cd $# && \
( [ -f Makefile ] || \
( aclocal && \
autoheader && \
automake --foreign --add-missing && \
autoconf && \
configure ) ) && \
$(MAKE) \
)
Each subdirectory has a Makefile.am and configure.ac like this:
Makefile.am:
# Makefile.am in "sd1" and "sd2"
bin_PROGRAMS = app
app_SOURCES = source.c
configure.ac:
AC_PREREQ(2.59)
AC_INIT([app], [1.00], [<suport#domain>])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
# Checks for header files.
AC_HEADER_STDC
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
# Output configuration files.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
I expected this to work, but autotools are embedding REPO_VERSION in the makefile when run, and changes in the main Makefile's REPO_VERSION are ignored in further builds.
A piece of an output looks like this:
== Building sd1 ==
[ CPPFLAGS = "-DREPO_VERSION="1050"" ]
( cd sd1 && \
( [ -f Makefile ] || \
( aclocal && \
autoheader && \
automake --foreign --add-missing && \
autoconf && \
configure ) ) && \
make \
)
make[1]: Entrando no diretório `./recursive/sd1'
make all-am
make[2]: Entrando no diretório `./recursive/sd1'
gcc -DHAVE_CONFIG_H -I. -DREPO_VERSION=\"1049M\" -g -O2 -MT source.o -MD -MP -MF .deps/source.Tpo -c -o source.o source.c
mv -f .deps/source.Tpo .deps/source.Po
gcc -g -O2 -o app source.o
make[2]: Saindo do diretório `./recursive/sd1'
make[1]: Saindo do diretório `./recursive/sd1'
The program outputs:
> ./sd1/appVersão = [1049M].
This clearly is not what I wanted.
Can anybody here please give a way to fix this?
Thanks.
In your top level make file add
export REPO_VERSION
and modify each Makefile.am to have
REPO_VERSION ?= unknown
AM_CPPFLAGS = -DREPO_VERSION="$(REPO_VERSION)"
The export directive makes it so that the value of REPO_VERSION is exported to recursive make invocations. The Makefile.am snippet sets a default value for REPO_VERSION if it is not given (e.g. make is run from the shell in the subdirectory) and AM_CPPFLAGS specifies the default value of CPPFLAGS for all targets in that Makefile. If you have a target specific _CPPFLAGS variable, you should either add $(AM_CPPFLAGS) to that or include the -DREPO_VERSION="$(REPO_VERSION)" in it. With a bit more effort you can add some stuff into the configure.ac files so that the default for REPO_VERSION can be set at configure time.
You are trying to pass CPPFLAGS via the environment, but I don't see where the invocation of configure is getting CPPFLAGS set in its environment. Try passing it at the command line:
$(SUBDIRS):
$(ECHO) "== Building $# =="
$(ECHO) " [ CPPFLAGS = \"$(CPPFLAGS)\" ]"
cd $# && autoreconf -i && ./configure CPPFLAGS=$(CPPFLAGS) && $(MAKE)
Also, you are only running configure once. After the Makefile exists, you do not rerun configure, so you never reset the value of CPPFLAGS in the subdirectory.
Setting the version at configure time is very inconvenient. Take a look here for some techinques that allow the version to be set at make time.

Resources