Makefile error in Eclipse with arduino due - makefile

I am trying to build a code on Ubuntu 12.04 using Eclipse with Arduino Due.
Every time I am getting the error in the console as -
make all
make: *** No rule to make target ArduinoLib5.a, needed by all. Stop.
My makefile is below : Please have a look and let me know how can I fix the error.
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
ifneq ($(strip $(ASM_DEPS)),)
-include $(ASM_DEPS)
endif
ifneq ($(strip $(CC_DEPS)),)
-include $(CC_DEPS)
endif
ifneq ($(strip $(CPP_DEPS)),)
-include $(CPP_DEPS)
endif
ifneq ($(strip $(CXX_DEPS)),)
-include $(CXX_DEPS)
endif
ifneq ($(strip $(C_UPPER_DEPS)),)
-include $(C_UPPER_DEPS)
endif
ifneq ($(strip $(S_UPPER_DEPS)),)
-include $(S_UPPER_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
EXECUTABLES += \
USER_OBJS \
SECONDARY_FLASH += \
ArduinoLib5.hex \
SECONDARY_LIST += \
ArduinoLib5.lst \
SECONDARY_SIZE += \
ArduinoLib5.siz \
# All Target
all: ArduinoLib5.a
# Tool invocations
#echo 'No tool found that can build the extension specified with the build artifact name $#'
USER_OBJS: $(OBJS) $(USER_OBJS)
#echo 'Invoking: ARM Sourcery Linux GCC C++ Linker'
arm-none-eabi-g++ -Wl,-Map,ArduinoLib5.map -mcpu=cortex-m3 -mthumb -g -ggdb -o "USER_OBJS" $(OBJS) $(USER_OBJS) $(LIBS)
#echo 'Finished building: $#'
#echo ' '
ArduinoLib5.hex: ArduinoLib5.a
#echo 'Invoking: ARM Sourcery Linux GNU Create Flash Image'
arm-none-eabi-objcopy -O ihex ArduinoLib5.a "ArduinoLib5.hex"
#echo 'Finished building: $#'
#echo ' '
ArduinoLib5.lst: ArduinoLib5.a
#echo 'Invoking: ARM Sourcery Linux GNU Create Listing'
arm-none-eabi-objdump -h -S ArduinoLib5.a > "ArduinoLib5.lst"
#echo 'Finished building: $#'
#echo ' '
ArduinoLib5.siz: ArduinoLib5.a
#echo 'Invoking: ARM Sourcery Linux GNU Print Size'
arm-none-eabi-size --format=berkeley ArduinoLib5.a
#echo 'Finished building: $#'
#echo ' '
# Other Targets
clean:
-$(RM) $(OBJS)$(C_DEPS)$(SECONDARY_FLASH)$(CXX_DEPS)$(S_UPPER_DEPS)$(SECONDARY_LIST)$(C++_DEPS)$(SECONDARY_SIZE)$(ASM_DEPS)$(CC_DEPS)$(CPP_DEPS)$(EXECUTABLES)$(C_UPPER_DEPS) ArduinoLib5.a
-#echo ' '
.PHONY: all clean dependents
.SECONDARY:
-include ../makefile.targets

you're indeed missing a rule which name is ArduinoLib5.a: or a ArduinoLib5.a file in current directory.
And I don't get your all rule. If it relies on the already existing ArduinoLib5.a file, it would do nothing. If it relies on a missing rule that generates ArduinoLib5.a, then it would not do "all" (i.e. not going through the .hex/.lst/.siz rules) but only that file.
Furthermore, looking at what the all rule does, I don't understand what $(OBJS)/$(USER_OBJS) are... but maybe they're given in env by eclipse!
Overall, your Makefile looks totally wrong to me.

Related

How to use python "include" and "libs" path in a windows makefile to compile all python embedded C++ program in a folder?

Makefile specified in this question, compiling all the cpp programs in a folder but not with python embedded cpp programs.
all: myUB
sourcesC := $(wildcard ../src/*.cpp)
objectsC := $(patsubst %.cpp,%.o,$(sourcesC))
INPATH=-I"C:/Python27/include"
LIBPATH=-L"C:/Python27/libs"-lpython27
myUB:
#echo 'Building target $#'
g++ -O0 -Wall -c -g3 -fmessage-length=0 \
$(sourcesC)
del *.o
clean:
Your final makefile could look somthing like:
all: myUB
sourcesC := $(wildcard ../src/*.cpp)
# Not used
#objectsC := $(patsubst %.cpp,%.o,$(sourcesC))
INC = -IC:\Python27\include
LIBS = -LC:\Python27\libs -lpython27
myUB:
#echo 'Building target $#'
g++ -O0 -Wall -g3 -fmessage-length=0 -o myprog.out $(sourcesC) $(INC) $(LIBS)
clean:
rm myprog.out
update
For the undefined ref to WinMain(), it means the linker can't find this function in your code. Either you need to include a library/object that contains it or you can define it yourself in a cpp file like:
#include <windows.h>
int WINAPI (*MyDummyReferenceToWinMain)(HINSTANCE hInstance, ..., int
nShowCmd ) = &WinMain;
I got the function template from here.
But this seems to mean that you are creating a windows application instead of a console app which uses int main(...) entry point.
Update2
I have made a new makefile to do what you have asked for in your latest comment which seems to be to create one executable per source file - I am assuming each source file has its own main.
# Build vars
CXX = g++
CXX_FLAGS = -O0 -Wall -g3
INC = -IC:\Python27\includ
LIBS = -LC:\Python27\libs -lpython27
# Sources
SRC_DIR=src
SOURCES = $(wildcard $(SRC_DIR)/*.cpp)
$(info SOURCES: $(SOURCES))
# Executables
EXE_DIR=bin
EXECUTABLES = $(subst $(SRC_DIR)/,$(EXE_DIR)/,$(subst cpp,out,$(SOURCES)))
$(info EXECUTABLES: $(EXECUTABLES))
$(info ----)
# Directories
DIRS = $(EXE_DIR)
# Rule to create folders and compile executables
all: $(DIRS) $(EXECUTABLES)
# Pattern rule to build each executable
$(EXE_DIR)/%.out : $(SRC_DIR)/%.cpp
#echo "compiling $< --> $#"
#$(CXX) $(CXX_FLAGS) -o $# $< $(INC) $(LIBS)
# Rule to create output dirs
$(DIRS):
#echo "Creating output folders"
#mkdir -p $(EXE_DIR)
# Rule to clean up
clean:
#echo "Cleaning"
#rm -rf $(EXE_DIR)
This should create one executable in the folder bin/ for each source file (.cpp) in folder src/.

Convert Makefile into CMakeLists, where to start

I searched on the inet but I did not find any clear answer. Could you point me in the right direction on how to convert a Makefile into a CMakeLists?
I want to do that because I am new both to makefile and to cmake. In my job CMake is more used and since I need to start using one of them I prefer having everything in CMake. I know CMake is generating a Makefile but for me CMake is way easier to read than a Makefile.
I have the following Makefile:
PREFIX ?= /usr/local
CC = gcc
AR = ar
CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
APRILTAG_SRCS := $(shell ls *.c common/*.c)
APRILTAG_HEADERS := $(shell ls *.h common/*.h)
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
TARGETS := libapriltag.a libapriltag.so
# LIBS := -Lusr/include/flycapture
.PHONY: all
all: $(TARGETS)
#$(MAKE) -C example all
.PHONY: install
install: libapriltag.so
#chmod +x install.sh
#./install.sh $(PREFIX)/lib libapriltag.so #this should be the line that install the library
#./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
#sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
#./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
#rm apriltag.pc
#ldconfig
libapriltag.a: $(APRILTAG_OBJS)
#echo " [$#]"
#$(AR) -cq $# $(APRILTAG_OBJS)
libapriltag.so: $(APRILTAG_OBJS)
#echo " [$#]"
#$(CC) -fPIC -shared -o $# $^
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS)
.PHONY: clean
clean:
#rm -rf *.o common/*.o $(TARGETS)
#$(MAKE) -C example clean
I am not asking you to do my job but I would like to have some kind of guide or a good link where to look.
The project contains both C and C++ programming languages.
I started creating a new CMakeLists.txt file, but it is still not working. It gives me the following errors:
You have called ADD_LIBRARY for library librapriltag.a without any source files. This typically indicates a problem with your CMakeLists.txt file
-- Configuring done
CMake Error: Cannot determine link language for target "librapriltag.a".
CMake Error: CMake can not determine linker language for target: librapriltag.a
-- Generating done
-- Build files have been written to: .....
The CMakeLists.txt I started creating is the following:
project( apriltag2 C CXX)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_C_FLAGS "-std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4")
include_directories("/home/fschiano/Repositories/apriltag2")
include_directories("/home/fschiano/Repositories/apriltag2/common")
add_library( librapriltag.a )
The CMakeLists.txt which works is the following:
project( apriltag2 )
cmake_minimum_required(VERSION 2.8)
set(CMAKE_C_FLAGS "-std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4")
message("CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}")
file(GLOB apriltag_SRC "*.c")
file(GLOB apriltag_HEADERS "*.h")
set(APRILTAG_SRCS ${apriltag_SRC})
set(APRILTAG_HEADERS ${apriltag_HEADERS})
message(STATUS "CMAKE_CURRENT_LIST_DIR=${CMAKE_CURRENT_LIST_DIR}")
add_library(apriltag STATIC ${APRILTAG_SRCS})
target_include_directories(apriltag PUBLIC ${CMAKE_SOURCE_DIR})
target_compile_options(apriltag PUBLIC -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -O4)
install(TARGETS apriltag
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib)
install(DIRECTORY CMAKE_CURRENT_LIST_DIR/include/
DESTINATION CMAKE_CURRENT_LIST_DIR/include/
FILES_MATCHING PATTERN *.h)
EDIT:
Something is still not right. If I want to change something in my library, like something which is in /home/fschiano/Repositories/apriltag2/common
If I use the Makefile which I had before doing all these modifications and I do:
make
do some modifications in the files I wanted to modify
sudo make install, which would give me the following output:
/usr/local/lib/libapriltag.so
/usr/local/include/apriltag/apriltag.h
/usr/local/include/apriltag/common/g2d.h
/usr/local/include/apriltag/common/getopt.h
/usr/local/include/apriltag/common/homography.h
/usr/local/include/apriltag/common/image_f32.h
/usr/local/include/apriltag/common/image_u8.h
/usr/local/include/apriltag/common/image_u8x3.h
/usr/local/include/apriltag/common/matd.h
/usr/local/include/apriltag/common/math_util.h
/usr/local/include/apriltag/common/pnm.h
/usr/local/include/apriltag/common/postscript_utils.h
/usr/local/include/apriltag/common/string_util.h
/usr/local/include/apriltag/common/svd22.h
/usr/local/include/apriltag/common/thash_impl.h
/usr/local/include/apriltag/common/timeprofile.h
/usr/local/include/apriltag/common/time_util.h
/usr/local/include/apriltag/common/unionfind.h
/usr/local/include/apriltag/common/workerpool.h
/usr/local/include/apriltag/common/zarray.h
/usr/local/include/apriltag/common/zhash.h
/usr/local/include/apriltag/common/zmaxheap.h
/usr/local/include/apriltag/tag16h5.h
/usr/local/include/apriltag/tag25h7.h
/usr/local/include/apriltag/tag25h9.h
/usr/local/include/apriltag/tag36artoolkit.h
/usr/local/include/apriltag/tag36h10.h
/usr/local/include/apriltag/tag36h11.h
/usr/local/lib/pkgconfig/apriltag.pc
/sbin/ldconfig.real: /usr/lib/libstdc++.so.5 is not a symbolic link
and the modifications would take effect.
Now, if I remove the Makefile and I do:
cmake .
make
do some modifications in the files I wanted to modify
sudo make install, it gives me the following output:
Install the project...
-- Install configuration: ""
-- Up-to-date: /usr/local/lib/libapriltag.a
So it seems that the install part of the CMakeLists.txt is not right!
The file install.sh is the following.
#!/bin/sh -e
# Usage: install.sh TARGET [RELATIVE PATHS ...]
#
# e.g. ./install.sh /usr/local foo/file1 foo/file2 ...
# This creates the files /usr/local/foo/file1 and /usr/local/foo/file2
TARGETDIR=$1
shift
for src in "$#"; do
dest=$TARGETDIR/$src
mkdir -p $(dirname $dest)
cp $src $dest
echo $dest
done
Could you try to help me?
Thanks
Let's go through that step-by-step:
PREFIX ?= /usr/local
We ignore that, as it's the default. Can be overwritten by CMAKE_INSTALL_PREFIX.
CC = gcc
AR = ar
Ignore these as well. Use CMAKE_C_COMPILER and CMAKE_CXX_COMPILER to forcibly switch the compiler.
CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
They are pretty special for gcc-like compilers. Set them conditionally for CMAKE_C_COMPILER_ID MATCHES GNU further down after defining the target.
The standard is set by set(C_STANDARD 98) and set(CXX_STANDARD 98).
APRILTAG_SRCS := $(shell ls *.c common/*.c)
Define a variable listing all the source files individually: set(APRILTAG_SRCS ...)
APRILTAG_HEADERS := $(shell ls *.h common/*.h)
Define a variable listing all the header file individually: set(APRILTAG_HEADERS ...). However, you don't really need them anywhere (unless you want Visual Studio to list them).
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
In most cases, you don't need that. For those rare cases there are Object Libraries.
TARGETS := libapriltag.a libapriltag.so
# LIBS := -Lusr/include/flycapture
We define our libraries here with add_library:
add_library(apriltag ${APRILTAG_SRCS})
target_include_directories(apriltag PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/apriltag)
target_compile_options(apriltag PUBLIC -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -O4)
The switch between static and shared is done via BUILD_SHARED_LIBS on invocation of CMake.
.PHONY: all
all: $(TARGETS)
#$(MAKE) -C example all
Nothing to do here. CMake will automatically create that.
.PHONY: install
install: libapriltag.so
#chmod +x install.sh
#./install.sh $(PREFIX)/lib libapriltag.so #this should be the line that install the library
#./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
#sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
#./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
#rm apriltag.pc
#ldconfig
CMake will ease this up by a magnitude:
install(TARGETS apriltag
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib)
install(DIRECTORY include/
DESTINATION include/
FILES_MATCHING PATTERN *.h)
That will install the library static and shared library (whatever exists) and the header files.
libapriltag.a: $(APRILTAG_OBJS)
#echo " [$#]"
#$(AR) -cq $# $(APRILTAG_OBJS)
libapriltag.so: $(APRILTAG_OBJS)
#echo " [$#]"
#$(CC) -fPIC -shared -o $# $^
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS)
All this is not needed.
.PHONY: clean
clean:
#rm -rf *.o common/*.o $(TARGETS)
#$(MAKE) -C example clean
You don't need that. CMake will generate a clean target automatically.
Judging from TARGETS := libapriltag.a libapriltag.so, you'll defintely need add_library command to create targets.
Instead of gathering souces to be compiled using wildcards like APRILTAG_SRCS := $(shell ls *.c common/*.c) it is recommended to list them explicitly in add_library call. But if you really want to list them automatically, see file(GLOB ...) command. (There are some important things to be aware of, though, see Specify source files globally with GLOB?).
The clean target would be generated automatically by CMake.
Finally, see the documentation for install() command to create install rules.
Compiler flags are set using set(CMAKE_C_FLAGS "blabla"), or appended using set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} blabla").

MinGW possibly linking to 64bit dlls

I'm trying to get SFML to work with Eclipse but I'm unsuccessfull(running MinGW 3.17-2 and gcc 4.8.1)
The file is compiled but when I try to run it I get the following error:
Looking in my MinGW\bin folder I can only see a libgcc_s_dw2-1.dll file and after some searching it appears that the dll asked for is for a 64-bit version? My OS is 64 bit but both MinGW and the SFML libraries all 32-bit.
How can I resolve this?
Makefile:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(CC_DEPS)),)
-include $(CC_DEPS)
endif
ifneq ($(strip $(C++_DEPS)),)
-include $(C++_DEPS)
endif
ifneq ($(strip $(C_UPPER_DEPS)),)
-include $(C_UPPER_DEPS)
endif
ifneq ($(strip $(CXX_DEPS)),)
-include $(CXX_DEPS)
endif
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
ifneq ($(strip $(CPP_DEPS)),)
-include $(CPP_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: Test
# Tool invocations
Test: $(OBJS) $(USER_OBJS)
#echo 'Building target: $#'
#echo 'Invoking: Cross G++ Linker'
g++ -L"F:\Libs\SFML-2.2\lib" -o "Test" $(OBJS) $(USER_OBJS) $(LIBS)
#echo 'Finished building target: $#'
#echo ' '
# Other Targets
clean:
-$(RM) $(CC_DEPS)$(C++_DEPS)$(EXECUTABLES)$(OBJS)$(C_UPPER_DEPS)$(CXX_DEPS)$(C_DEPS)$(CPP_DEPS) Test
-#echo ' '
.PHONY: all clean dependents
.SECONDARY:
-include ../makefile.targets
objects.mk:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
USER_OBJS :=
LIBS := -lsfml-graphics-d -lsfml-system-d -lsfml-window-d
sources.mk:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
C_UPPER_SRCS :=
CXX_SRCS :=
C++_SRCS :=
OBJ_SRCS :=
CC_SRCS :=
ASM_SRCS :=
C_SRCS :=
CPP_SRCS :=
O_SRCS :=
S_UPPER_SRCS :=
CC_DEPS :=
C++_DEPS :=
EXECUTABLES :=
OBJS :=
C_UPPER_DEPS :=
CXX_DEPS :=
C_DEPS :=
CPP_DEPS :=
# Every subdirectory with source files must be described here
SUBDIRS := \
. \
subdir.mk
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS += \
../main.cpp
OBJS += \
./main.o
CPP_DEPS += \
./main.d
# Each subdirectory must supply rules for building sources it contributes
%.o: ../%.cpp
#echo 'Building file: $<'
#echo 'Invoking: Cross G++ Compiler'
g++ -I"F:\Libs\SFML-2.2\include" -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"$(#:%.o=%.d)" -MT"$(#:%.o=%.d)" -o "$#" "$<"
#echo 'Finished building: $<'
#echo ' '
Due to the way name mangling and non-standardized ABI work in C++, there is unfortunately about no compatibility between different versions of compilers. In your case, you're even trying to use a library compiled with a compiler from a different "MinGW" project than your current compiler is. But even if you were using the same "type" of compiler, C++ libraries usually aren't reusable across minor or patch versions.
First of I really recommend to not use the original MinGW project and rather go for a compiler based on the MinGW-w64 project. If you want reasons for that, you can ask Google, there are enough discussion about it.
Second you either need to pick a compiler that matches on of the SFML packages OR you need to build SFML yourself.
For the GCC 4.9.2 MinGW (DW2) - 32-bit package I used this compiler.
For the GCC 4.7.1 TDM (SJLJ) - 32-bit package I used the compiler that shipped with this Code::Blocks package.
For the GCC 4.8.1 TDM (SJLJ) - 32-bit package I used the compiler that shipped with this Code::Blocks package.
And third, if you want the latest development version of SFML using the latest compiler versions, you can check out my Nightly Builds.

Automatic dependency resolution using GNU Makefile

I'm writing a piece of software that utilizes a Makefile for compilation, originally I had a rule setup for each file however this proved to be too cumbersome whenever I added a new file. To try and automate the process I did some research and learnt that GCC/G++ can automatically build Makefile rules with the -M flag.
There are many examples of this being done with a simple directory structure however my ideal directory structure looks like this:
src/
kernel.hpp kernel.cpp
Types/
String.cpp
String.hpp
Drivers/IO-Ports/
CMOS.cpp
CMOS.hpp
...
build/
DEPS/
kernel.d
Types/String.d
...
OBJ/
kernel.o
Types/String.o
...
My current Makefile:
CCHOME=/home/dan/opt/cross/bin
CC=#$(CCHOME)/i586-elf-g++
CFLAGS=-ffreestanding -O2 -Wextra -Wall -fno-exceptions -fno-rtti
KernelName=CPlusKern
QEMU=qemu-system-x86_64 -monitor stdio
SrcDIR=src
SourceDIRS:=$(shell find $(SrcDIR) -type d)
SrcFILES=$(shell find $(SrcDIR) -type f -name *.cpp)
HdrFILES=$(shell find $(SrcDIR) -type f -name *.hpp)
DepDIR=$(BuildDIR)/DEPS
DepFILES0=$(subst $(SrcDIR), $(DepDIR),$(SrcFILES))
DepFILES=$(subst .cpp,.d,$(DepFILES0))
ObjDIR=$(BuildDIR)/OBJ
ObjDIRS=$(subst $(SrcDIR),$(ObjDIR),$(SourceDIRS))
ObjFILES0=$(subst $(SrcDIR), $(ObjDIR),$(SrcFILES))
ObjFILES=$(subst .cpp,.o,$(ObjFILES0))
BuildDIR=build
BuildDIRS=$(BuildDIR) $(ObjDIR) $(DepDIR)
all: assemble compile run
image: assemble compile build-image run-image
debug:
#echo "BuildDIRS: " $(BuildDIRS)
#echo "DepFiles: " $(DepFILES)
#echo "SrcFiles: " $(SrcFILES)
#echo "ObjFiles: " $(ObjFILES)
./src/kernel.o: ./src/kernel.cpp
#echo $(CC) $(CFLAGS) -MMD -MP -MF $< -o $(subst $(SrcDIR), $(ObjDIR),$#)
./src/kernel.cpp:
dir:
#echo "Making Build Dirs..."
#-mkdir -p $(BuildDIRS)
compile: dir $(ObjFILES)
# #echo "Compiling Source Files: " $(SrcFILES)
assemble: dir boot.o
#echo "Assembling Core Files..."
boot.o: $(SrcDIR)/boot.s
#$(CCHOME)/i586-elf-as $(SrcDIR)/boot.s -o $(ObjDIR)/boot.o
build: %.o
echo "Building Kernel Binary..."
#$(CC) -T linker.ld -o $(KernelName).bin -ffreestanding -O2 -nostdlib $(SrcFILES)-lgcc
build-image: build
#echo "Building Kernel Image..."
#cp $(KernelName).bin isodir/boot/$(KernelName).bin
#Scripts/MakeGrub.sh $(KernelName) isodir/boot/grub
grub-mkrescue -o $(KernelName).iso isodir
%.o: %.cpp Makefile
#echo "Building Object $#"
$(CC) $(CFLAGS) -MMD -MP -MF $(subst $(SrcDIR),$(DepDIR),$#) -o $(subst $(SrcDIR), $(ObjDIR),$#)
run:
#echo "Starting QEMU"
#$(QEMU) -kernel $(KernelName).bin
run-image:
#echo "Starting QEMU"
#$(QEMU) -bios OVMF.fd -cdrom $(KernelName).iso
clean:
#echo "Cleaning Build Directories..."
-#rm -R $(BuildDIR) ./isodir
-#$(RM) $(KernelName).bin $(KernelName).iso
I thought this might do the trick however make throws an error:
make: *** No rule to make target `build/OBJ/VGA.o', needed by `compile'. Stop.
I can't determine how to make the rule:
%.o: %.cpp Makefile
$(CC) $(CFLAGS) -MMD -MP -MF $(subst $(SrcDIR),$(DepDIR),$#) -o $(subst $(SrcDIR), $(ObjDIR),$#)
apply to every .cpp file. As far as I know wildcards cannot be used in rule definitions.
I'm not sure if this helps but the path/name of each source file is stored in the $(SrcFILES) variable.
Just to clarify, here is an expanded version of the above rule:
/home/dan/opt/cross/bin/i586-elf-g++ -ffreestanding -O2 -Wextra -Wall -fno-exceptions -fno-rtti -MMD -MP -MF src/kernel.cpp -o build/OBJ/kernel.o
And the generated dependency file for this instance:
kernel.o: src/kernel.cpp src/kernel.hpp src/Globals.hpp \
src/VGATerminal.hpp src/Types/String.hpp src/Types/../Globals.hpp \
src/VGA.hpp src/IO/Read.hpp src/IO/Write.hpp \
src/Drivers/IO-Ports/CMOS.hpp src/Drivers/IO-Ports/../../IO/Read.hpp \
src/Drivers/IO-Ports/../../IO/Write.hpp
This is my first post here so feedback on my question is appreciated :)
Hopefully I can get this out of the way and get back to developing my code.
EDIT:
The rule provided by #Beta worked without a problem, All of my Object files successfully build and are output in the right place. This rule even picked up build/OBJ/Drivers/IO-Ports/CMOS.o and build/OBJ/Drivers/PS2.o.
So now I can happily build all of the Objects individually if I pass the filename however I think I still need dependency resolution so that I don't have to write a rule for each file.
This may take a few iterations.
The first problem is that you have a target, build/OBJ/VGA.o and no corresponding rule. The rule
%.o: %.cpp Makefile
...
doesn't fit; it can build build/OBJ/VGA.o from build/OBJ/VGA.cpp, but there's no such source file.
So for a first step, if the source file is src/whatever/VGA.cpp, try this rule:
build/OBJ/%.o: src/whatever/%.cpp
...
and tell us the result.
EDIT:
Good, now try this:
build/OBJ/%.o: src/%.cpp
...

Makefile: set parameters for commands executed by implicit rules (CFLAGS, LDFLAGS)

I'm very new to makefiles. I'm reading the GNU-make manual, but I'm still unclear about how to set the parameters for the compiler and the linker when they are executed by an implicit rule.
This is part of the makefile, note there is no explicit declaration of how to compile and link everything:
.PHONY: $(TARGET) build_libs
all: build_libs $(TARGET)
$(TARGET):
#echo "============> building target: $(TARGET)"
#$(MAKE) -C $(SDK_PATH)/VP_SDK/Build $(TMP_SDK_FLAGS) $(SDK_FLAGS) $(MAKECMDGOALS) USE_LINUX=yes
mv $(ARDRONE_TARGET_DIR)/ardrone_testing_tool $(TARGET)
mv $(TARGET) $(ARDRONE_TARGET_DIR)/
#echo "============> end building target: $(TARGET)"
$(MAKECMDGOALS): build_libs
#echo "============> making cmd goals"
#$(MAKE) -C $(SDK_PATH)/VP_SDK/Build $(TMP_SDK_FLAGS) $(SDK_FLAGS) $(MAKECMDGOALS) USE_LINUX=yes
#echo "============> end making cmd goals"
build_libs:
#echo "============> building libs"
#$(MAKE) -C $(SDK_PATH)/Soft/Build $(TMP_SDK_FLAGS) $(SDK_FLAGS) $(MAKECMDGOALS) USE_LINUX=yes
#echo "============> end building libs"
That makefile builds an executable from the source files and library. But I want to compile them into a shared library. Because of that I (think I) have to add the -fPIC parameter to cc and the -shared and -soname parameters to ld. I've tried with CFLAGS=-fPIC and LDFLAGS=-shared -soname foo, which didn't work. Has anybody suggestions on how to get a shared libarary? If you need more information please just ask. Thanks in advance!
UPDATE: The makefile in $(SDK_PATH)/Soft/Build:
GEN_CUSTOM_HEADER:=../Common/generated_custom.h
include custom.makefile
include config.makefile
GNUTOOLS_PATH=/usr/local/$(GNUTOOLS_VERSION)/bin
define ADD_RULE_TEMPLATE
TO_BUILD+=build_$(1)
endef
# Add rule for each target
$(foreach target,$(TARGETS),$(eval $(call ADD_RULE_TEMPLATE,$(target))))
.PHONY: linux_sample svn_update $(TO_BUILD) build_libs $(MAKECMDGOALS)
all: $(GEN_CUSTOM_HEADER) build_libs $(TO_BUILD)
$(GEN_CUSTOM_HEADER): custom.makefile
#echo "#ifndef _GENERATED_CUSTOM_CONFIGURATION_H_" > $#
#echo "#define _GENERATED_CUSTOM_CONFIGURATION_H_" >> $#
#echo >> $#
#echo "#if defined(BR2_PACKAGE_BCM4318_AP)" >> $#
#echo "# define AP" >> $#
#echo "#else" >> $#
#echo "# define STA" >> $#
#echo "#endif" >> $#
#echo "#define CURRENT_NUM_VERSION_SOFT \"$(MAJOR_VERSION).$(MINOR_VERSION).$(MODIF_VERSION)\"" >> $#
#echo "#define CURRENT_BUILD_DATE \"$(shell date +%F\ %H:%M)\"" >> $#
#echo >> $#
ifeq ("$(VIDEO_YUV)","yes")
#echo "#define USE_VIDEO_YUV" >> $#
endif
ifeq ("$(RECORD_VISION_DATA)","yes")
#echo "#define RECORD_VISION_DATA" >> $#
endif
#echo >> $#
#echo "#define WIFI_NETWORK_NAME \"$(WIFI_NETWORK_NAME)\"" >> $#
#echo "#define WIFI_BROADCAST \"$(WIFI_BROADCAST)\"" >> $#
#echo "#define WIFI_ARDRONE_IP \"$(WIFI_ARDRONE_IP)\"" >> $#
#echo >> $#
#echo "#if defined(__linux__) || defined(USE_MINGW32)" >> $#
#echo "# define WIFI_MOBILE_IP \"$(WIFI_MOBILE_IP)\"" >> $#
#echo "# define WIRED_ITFNAME \"$(WIRED_ITFNAME)\"" >> $#
#echo "#endif // ! __linux__" >> $#
#echo >> $#
#echo >> $#
#echo "#endif // ! _GENERATED_CUSTOM_CONFIGURATION_H_" >> $#
ifneq "$(MAKECMDGOALS)" ""
ifneq "$(MAKECMDGOALS)" "clean"
ifneq "$(MAKECMDGOALS)" "update"
$(MAKECMDGOALS):
#echo -e "\nCannot make what you ask me to do :-("
else
$(MAKECMDGOALS): svn_update
endif
endif
endif
$(MAKECMDGOALS): build_libs $(TO_BUILD)
checkpackages:
ifeq ($(IPHONE_MODE),yes)
sh $(shell pwd)/check_dependencies.sh iphone RELEASE_BUILD=$(RELEASE_BUILD) $(MAKECMDGOALS)
else
ifeq ($(USE_LINUX),yes)
sh $(shell pwd)/check_dependencies.sh static RELEASE_BUILD=$(RELEASE_BUILD) $(MAKECMDGOALS)
else
ifeq ($(USE_ANDROID),yes)
sh $(shell pwd)/check_dependencies.sh android_no_neon RELEASE_BUILD=$(RELEASE_BUILD) $(MAKECMDGOALS)
endif
endif
endif
define GENERIC_RULES_TEMPLATE
build_$(1):
#$(MAKE) -C $(1) $(MAKECMDGOALS)
endef
$(foreach target,$(TARGETS),$(eval $(call GENERIC_RULES_TEMPLATE,$(target))))
build_libs: checkpackages
#$(MAKE) PC_TARGET=yes USE_ARDRONE_TOOL=yes TARGET=pc_ USE_MINGW32=no -C ../Lib/Build $(MAKECMDGOALS)
#$(MAKE) PC_TARGET=yes USE_ARDRONE_TOOL=no TARGET=pc_ USE_MINGW32=no -C ../Lib/Build $(MAKECMDGOALS)
ifeq ("$(MINGW32_MODE)","yes")
ifeq ($(shell which i586-mingw32msvc-gcc 2> /dev/null),)
$(warning You need MinGW32 to compile My Ardrone lib for Windows if you want. (under Debian: apt-get install mingw32))
else
# #$(MAKE) PC_TARGET=yes TARGET=mingw32_ USE_MINGW32=yes TMP_SDK_FLAGS="USE_MINGW32=yes NO_COM=yes USE_BLUEZ=no" -C ../Lib/Build $(MAKECMDGOALS)
# #$(MAKE) PC_TARGET=yes TARGET=emb_mingw32_ USE_MINGW32=yes CONTROL_DLL=yes TMP_SDK_FLAGS="USE_MINGW32=yes NO_COM=yes USE_BLUEZ=no" -C ../Lib/Build $(MAKECMDGOALS)
endif
endif
ifeq ($(WIIMOTE_SUPPORT),yes)
# #$(MAKE) PC_TARGET=yes TARGET=pc_ TMP_SDK_FLAGS="USE_BLUEZ=yes" -C ../Lib/libcwiid $(MAKECMDGOALS)
endif
define svn_update_template
cd ../.. ; \
echo "Checking out tag $(1) of $(2) ..." ; \
if [ $(1) != head ] ; then \
svn co -r $(1) https://svn.ardrone.org/repo/ARDrone_API/$(2) ; \
else \
svn co https://svn.ardrone.org/repo/ARDrone_API/$(2) ; \
fi ; \
cd Soft/Build ;
endef
svn_update:
#-$(call svn_update_template,$(SDK_VERSION),ARDroneLib)
If custom.makefile and config.makefile are needed you can find them here: http://pastebin.com/H8PNKKhu
UPDATE 2: I just discovered this, located in $(SDK_PATH)/VP_SDK/Build: http://pastebin.com/3knnSkmy
Since you haven't showed us the makefile in $(SDK_PATH)/Soft/Build, I'm going to take a guess.
In the GNU Make manual, there is the list of variables used by implicit rules:
CFLAGS: Extra flags to give the C compiler.
LDFLAGS: Extra flags to give to compiler when they are supposed to invoke the linker 'ld'.
In addition, the catalogue of implicit rules mentions the LDLIBS variable that names libraries used in the implicit link rule. (The implicit link rule is fine when you have a single source file being linked or where one of the object files is the name of the final executable, otherwise you need to write an explicit linking rule.)
This isn't coming into focus. These appear to be generated makefiles, so they're hard to trace, there's clearly more going on than we're seeing (and I don't blame you for not posting everything), and I don't see where the build_libs rule leads, or any use of the linker, or anything that could build a static library. We could show you how to write an explicit rule to build a shared library, but without a list of sources or objects we wouldn't know what to put into that library.
This is getting desperate, but could you try the following:
1) make -C $(SDK_PATH)/Soft/Build (putting in the appropriate value for $(SDK_PATH)) and verify that this produces the static library.
2) make -n, capture the torrent of output and put it in pastebin. We'll try to see what rules it's using, which might lead to what we need.
I did it. Finally!!!
The solution: in $(SDK_PATH)/VP_SDK/Build there was a file named generic.makefile containing all the compiler and linker invocations. I had to add the -shared and -fPIC arguments to some of them. Sounds really simple, but nothing of that was documented so I first had to look for that hidden compiler/linker invocations...

Resources