I'm trying to write some C++ code for a Atmel SAM3S1 microcontroller. I'm Using the ASF Library with the FreeRTOS library included. I wrote a simple and small C++ wrapper (3 .cpp files) so I can easily inherit it in my device classes.
The Atmel SAM (datasheet) has 64KB Flash and 16KB RAM which I think is more then enough. although when I start compiling I get the message:
section `.text' will not fit in region `rom'
/usr/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/bin/ld: region `rom' overflowed by 13120 bytes
I use arm-none-eabi-g++ to compile and link everything.
When I clear the declared Class in Main.cpp the sizes are just fine so I think that is has something to do with C++. Can somebody explain to me what I'm doing wrong here?
Test.elf :
section size addr
.text 0x102c 0x400000
.ARM.exidx 0x8 0x40102c
.relocate 0x844 0x20000000
.bss 0x154 0x20000844
.stack 0x2000 0x20000998
.ARM.attributes 0x29 0x0
.comment 0x70 0x0
.debug_info 0x57d1 0x0
.debug_abbrev 0x1058 0x0
.debug_aranges 0x430 0x0
.debug_ranges 0xb00 0x0
.debug_macro 0xf50a 0x0
.debug_line 0x5024 0x0
.debug_str 0x46ec7 0x0
.debug_frame 0xe04 0x0
.debug_loc 0x31f1 0x0
Total 0x6a5a8
text data bss dec hex filename
0x1034 0x844 0x2154 14796 39cc Test.elf
These are my CPP files:
Main.cpp
#include <asf.h>
#include <MMA8652.h>
extern "C" {
extern void vApplicationStackOverflowHook(xTaskHandle *pxTask,
signed char *pcTaskName) {
}
}
int main(void) {
const taskConfig_t AccelTaskConfig = { "AccelRx", 3, 100 };
MMA8652 Accelero(AccelTaskConfig);
return(0);
}
Task.h
//#ifndef TASK_H
//#define TASK_H
#include <inttypes.h>
typedef struct {
char *taskName;
uint8_t priority;
uint16_t stackSize;
} taskConfig_t;
class Task {
private:
public:
Task(char *taskName, uint8_t priority, uint16_t stackSize);
~Task();
friend void run_helper(void *arg) {
return static_cast<Task*>(arg)->run();
}
virtual void run(void) const = 0;
protected:
};
//#endif
Task.cpp
#include <Task.h>
#include <asf.h>
void run_helper(void *arg);
Task::Task( char *taskName,
uint8_t priority,
uint16_t stackSize ) {
// check for minimal stacksize
if(stackSize < configMINIMAL_STACK_SIZE) {
stackSize = configMINIMAL_STACK_SIZE;
}
// check priority val
if(priority > configMAX_PRIORITIES) {
priority = configMAX_PRIORITIES;
}
// create a new FreeRTOS task with func ptr to run() member
xTaskCreate( &run_helper, (const signed char *) taskName,
stackSize, (Task*)this, priority, NULL);
}
MMA8652.h
#ifndef MMA8652_H
#define MMA8652_H
#include <Task.h>
class MMA8652: public Task {
private:
public:
void run(void) const;
MMA8652(const taskConfig_t &tConfig);
~MMA8652(void);
};
#endif // MMA8652_H
MMA8652.cpp
#include <asf.h>
#include <MMA8652.h>
MMA8652::MMA8652(const taskConfig_t &tConfig) :
Task(tConfig.taskName, tConfig.priority, tConfig.stackSize) {
}
void MMA8652::run(void) const {
pio_set_pin_high(TESTLED_GPIO);
vTaskDelay(1000);
pio_set_pin_low(TESTLED_GPIO);
vTaskDelay(1000);
}
linker_script.ld
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00010000 /* Flash, 64K */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
}
/* The stack size used by the application. NOTE: you need to adjust */
__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4;
/* Section Definitions */
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
/* Support C constructors, and C destructors in both user code
and the C library. This also provides support for C++ code. */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; /* End of text section */
} > rom
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + __stack_size__;
. = ALIGN(8);
_estack = .;
} > ram
. = ALIGN(4);
_end = . ;
}
config.mk
# Path to top level ASF directory relative to this project directory.
PRJ_PATH = ASF
# Target CPU architecture: cortex-m3, cortex-m4
ARCH = cortex-m3
# Target part: none, sam3n4 or sam4l4aa
PART = sam3s1ab
# Application target name. Given with suffix .a for library and .elf for a
# standalone application.
TARGET_FLASH = $(PRJ_NAME).elf
TARGET_SRAM = $(PRJ_NAME).elf
# List of C source files.
CSRCS = \
Main.cpp \
lib/Task.cpp \
devices/MMA8652.cpp \
sam/boards/Board/init.c \
common/services/clock/sam3s/sysclk.c \
common/utils/interrupt/interrupt_sam_nvic.c \
common/utils/stdio/read.c \
common/utils/stdio/write.c \
sam/drivers/pio/pio.c \
sam/drivers/pio/pio_handler.c \
sam/drivers/pmc/pmc.c \
sam/drivers/pmc/sleep.c \
sam/utils/cmsis/sam3s/source/templates/exceptions.c \
sam/utils/cmsis/sam3s/source/templates/gcc/startup_sam3s.c \
sam/utils/cmsis/sam3s/source/templates/system_sam3s.c \
sam/utils/syscalls/gcc/syscalls.c \
thirdparty/freertos/freertos-7.0.0/source/croutine.c \
thirdparty/freertos/freertos-7.0.0/source/list.c \
thirdparty/freertos/freertos-7.0.0/source/portable/gcc/sam/port.c \
thirdparty/freertos/freertos-7.0.0/source/portable/memmang/heap_3.c \
thirdparty/freertos/freertos-7.0.0/source/queue.c \
thirdparty/freertos/freertos-7.0.0/source/tasks.c \
thirdparty/freertos/freertos-7.0.0/source/timers.c
# List of assembler source files.
ASSRCS =
# List of include paths.
INC_PATH = \
../lib/include \
../devices/include \
../config \
../ \
common/services/clock \
common/boards \
common/services/gpio \
common/services/ioport \
common/utils \
sam/drivers/pio \
sam/drivers/pmc \
sam/utils \
sam/utils/cmsis/sam3s/include \
sam/utils/cmsis/sam3s/source/templates \
sam/utils/header_files \
sam/utils/preprocessor \
thirdparty/CMSIS/Include \
thirdparty/CMSIS/Lib/GCC \
thirdparty/freertos/freertos-7.0.0/source/include \
thirdparty/freertos/freertos-7.0.0/source/portable/gcc/sam \
# Additional search paths for libraries.
LIB_PATH = \
thirdparty/CMSIS/Lib/GCC
# List of libraries to use during linking.
LIBS =
# Path relative to top level directory pointing to a linker script.
LINKER_SCRIPT_FLASH = sam/utils/linker_scripts/sam3s/sam3s1/gcc/flash.ld
LINKER_SCRIPT_SRAM = sam/utils/linker_scripts/sam3s/sam3s1/gcc/sram.ld
# Project type parameter: all, sram or flash
PROJECT_TYPE = flash
# Additional options for debugging. By default the common Makefile.in will
# add -g3.
DBGFLAGS =
# Application optimization used during compilation and linking:
# -O0, -O1, -O2, -O3 or -Os
OPTIMIZATION = -O3
# Extra flags to use when archiving.
ARFLAGS =
# Extra flags to use when assembling.
ASFLAGS =
# Extra flags to use when compiling.
CFLAGS =
# Extra flags to use when preprocessing.
#
# Preprocessor symbol definitions
# To add a definition use the format "-D name[=definition]".
# To cancel a definition use the format "-U name".
#
# The most relevant symbols to define for the preprocessor are:
# BOARD Target board in use, see boards/board.h for a list.
# EXT_BOARD Optional extension board in use, see boards/board.h for a list.
CPPFLAGS = \
-D __FREERTOS__ \
-D __SAM3S1B__ \
-D BOARD=BOARD \
-D printf=iprintf \
-D scanf=iscanf
# Extra flags to use when linking
LDFLAGS = \
# Pre- and post-build commands
PREBUILD_CMD =
POSTBUILD_CMD =
Makefile.sam.in
include config.mk
# Tool to use to generate documentation from the source code
DOCGEN ?= doxygen
# Look for source files relative to the top-level source directory
VPATH := $(PRJ_PATH)
# Output target file
project_type := $(PROJECT_TYPE)
# Output target file
ifeq ($(project_type),flash)
target := $(TARGET_FLASH)
linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_FLASH)
debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH)
else
target := $(TARGET_SRAM)
linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_SRAM)
debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM)
endif
# Output project name (target name minus suffix)
project := $(basename $(target))
# Output target file (typically ELF or static library)
ifeq ($(suffix $(target)),.a)
target_type := lib
else
ifeq ($(suffix $(target)),.elf)
target_type := elf
else
$(error "Target type $(target_type) is not supported")
endif
endif
# Allow override of operating system detection. The user can add OS=Linux or
# OS=Windows on the command line to explicit set the host OS.
#
# This allows to work around broken uname utility on certain systems.
ifdef OS
ifeq ($(strip $(OS)), Linux)
os_type := Linux
endif
ifeq ($(strip $(OS)), Windows)
os_type := windows32_64
endif
endif
os_type ?= $(strip $(shell uname))
ifeq ($(os_type),windows32)
os := Windows
else
ifeq ($(os_type),windows64)
os := Windows
else
ifeq ($(os_type),windows32_64)
os ?= Windows
else
ifeq ($(os_type),)
os := Windows
else
# Default to Linux style operating system. Both Cygwin and mingw are fully
# compatible (for this Makefile) with Linux.
os := Linux
endif
endif
endif
endif
# Output documentation directory and configuration file.
docdir := ../doxygen/html
doccfg := ../doxygen/doxyfile.doxygen
CROSS ?= arm-none-eabi-
AR := $(CROSS)ar
AS := $(CROSS)as
CC := $(CROSS)gcc
CPP := $(CROSS)gcc -E
CXX := $(CROSS)g++
LD := $(CROSS)g++
NM := $(CROSS)nm
OBJCOPY := $(CROSS)objcopy
OBJDUMP := $(CROSS)objdump
SIZE := $(CROSS)size
GDB := $(CROSS)gdb
RM := rm
ifeq ($(os),Windows)
RMDIR := rmdir /S /Q
else
RMDIR := rmdir -p --ignore-fail-on-non-empty
endif
# On Windows, we need to override the shell to force the use of cmd.exe
ifeq ($(os),Windows)
SHELL := cmd
endif
# Strings for beautifying output
MSG_CLEAN_FILES = "RM *.o *.d"
MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))"
MSG_CLEAN_DOC = "RMDIR $(docdir)"
MSG_MKDIR = "MKDIR $(dir $#)"
MSG_INFO = "INFO "
MSG_PREBUILD = "PREBUILD $(PREBUILD_CMD)"
MSG_POSTBUILD = "POSTBUILD $(POSTBUILD_CMD)"
MSG_ARCHIVING = "AR $#"
MSG_ASSEMBLING = "AS $#"
MSG_BINARY_IMAGE = "OBJCOPY $#"
MSG_COMPILING = "CC $#"
MSG_COMPILING_CXX = "CXX $#"
MSG_EXTENDED_LISTING = "OBJDUMP $#"
MSG_IHEX_IMAGE = "OBJCOPY $#"
MSG_LINKING = "LN $#"
MSG_PREPROCESSING = "CPP $#"
MSG_SIZE = "SIZE $#"
MSG_SYMBOL_TABLE = "NM $#"
MSG_GENERATING_DOC = "DOXYGEN $(docdir)"
# Don't use make's built-in rules and variables
MAKEFLAGS += -rR
# Don't print 'Entering directory ...'
MAKEFLAGS += --no-print-directory
# Function for reversing the order of a list
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
# Hide command output by default, but allow the user to override this
# by adding V=1 on the command line.
#
# This is inspired by the Kbuild system used by the Linux kernel.
ifdef V
ifeq ("$(origin V)", "command line")
VERBOSE = $(V)
endif
endif
ifndef VERBOSE
VERBOSE = 0
endif
ifeq ($(VERBOSE), 1)
Q =
else
Q = #
endif
arflags-gnu-y := $(ARFLAGS)
asflags-gnu-y := $(ASFLAGS)
cflags-gnu-y := $(CFLAGS)
cxxflags-gnu-y := $(CXXFLAGS)
cppflags-gnu-y := $(CPPFLAGS)
cpuflags-gnu-y :=
dbgflags-gnu-y := $(DBGFLAGS)
libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB))
ldflags-gnu-y := $(LDFLAGS)
flashflags-gnu-y :=
clean-files :=
clean-dirs :=
clean-files += $(wildcard $(target) $(project).map)
clean-files += $(wildcard $(project).hex $(project).bin)
clean-files += $(wildcard $(project).lss $(project).sym)
clean-files += $(wildcard $(build))
# Use pipes instead of temporary files for communication between processes
cflags-gnu-y += -pipe
asflags-gnu-y += -pipe
ldflags-gnu-y += -pipe
# Archiver flags.
arflags-gnu-y += rcs
# Always enable warnings. And be very careful about implicit
# declarations.
cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes
cflags-gnu-y += -Werror-implicit-function-declaration
cxxflags-gnu-y += -Wall
# IAR doesn't allow arithmetic on void pointers, so warn about that.
cflags-gnu-y += -Wpointer-arith
cxxflags-gnu-y += -Wpointer-arith
# Preprocessor flags.
cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC))
asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)')
# CPU specific flags.
cpuflags-gnu-y += -mcpu=$(ARCH) -mthumb -D=__$(PART)__
# Dependency file flags.
depflags = -MD -MP -MQ $#
# Debug specific flags.
ifdef BUILD_DEBUG_LEVEL
dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL)
else
dbgflags-gnu-y += -g3
endif
# Optimization specific flags.
ifdef BUILD_OPTIMIZATION
optflags-gnu-y = -O$(BUILD_OPTIMIZATION)
else
optflags-gnu-y = $(OPTIMIZATION)
endif
# Always preprocess assembler files.
asflags-gnu-y += -x assembler-with-cpp
# Compile C files using the GNU99 standard.
cflags-gnu-y += -std=gnu99
# Compile C++ files using the GNU++98 standard.
cxxflags-gnu-y += -std=gnu++98
# Don't use strict aliasing (very common in embedded applications).
cflags-gnu-y += -fno-strict-aliasing
cxxflags-gnu-y += -fno-strict-aliasing
# Separate each function and data into its own separate section to allow
# garbage collection of unused sections.
cflags-gnu-y += -ffunction-sections -fdata-sections
cxxflags-gnu-y += -ffunction-sections -fdata-sections
# Various cflags.
cflags-gnu-y += -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
cflags-gnu-y += -Wmain -Wparentheses
cflags-gnu-y += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
cflags-gnu-y += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
cflags-gnu-y += -Wshadow -Wbad-function-cast -Wwrite-strings
cflags-gnu-y += -Wsign-compare -Waggregate-return
cflags-gnu-y += -Wmissing-declarations
cflags-gnu-y += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
cflags-gnu-y += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
cflags-gnu-y += -Wunreachable-code
cflags-gnu-y += -Wcast-align
cflags-gnu-y += --param max-inline-insns-single=500
# Garbage collect unreferred sections when linking.
ldflags-gnu-y += -Wl,--gc-sections
# Use the linker script if provided by the project.
ifneq ($(strip $(linker_script)),)
ldflags-gnu-y += -Wl,-T $(linker_script)
endif
# Output a link map file and a cross reference table
ldflags-gnu-y += -Wl,-Map=$(project).map,--cref
# Add library search paths relative to the top level directory.
ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH))
a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__
c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y)
cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y)
l_flags = -Wl,--entry=Reset_Handler -Wl,--cref $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y)
ar_flags = $(arflags-gnu-y)
# Source files list and part informations must already be included before
# running this makefile
# If a custom build directory is specified, use it -- force trailing / in directory name.
ifdef BUILD_DIR
build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/)
else
build-dir =
endif
# Create object files list from source files list.
obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS))))
# Create dependency files list from source files list.
dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d))
clean-files += $(wildcard $(obj-y))
clean-files += $(dep-files)
clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y)))))
# Default target.
.PHONY: all
ifeq ($(project_type),all)
all:
$(MAKE) all PROJECT_TYPE=flash
$(MAKE) all PROJECT_TYPE=sram
else
ifeq ($(target_type),lib)
all: $(target) $(project).lss $(project).sym
else
ifeq ($(target_type),elf)
all: prebuild $(target) $(project).lss $(project).sym $(project).hex $(project).bin postbuild
endif
endif
endif
prebuild:
ifneq ($(strip $(PREBUILD_CMD)),)
#echo $(MSG_PREBUILD)
$(Q)$(PREBUILD_CMD)
endif
postbuild:
ifneq ($(strip $(POSTBUILD_CMD)),)
#echo $(MSG_POSTBUILD)
$(Q)$(POSTBUILD_CMD)
endif
# Clean up the project.
.PHONY: clean
clean:
#$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES))
$(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),)
#$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS))
# Remove created directories, and make sure we only remove existing
# directories, since recursive rmdir might help us a bit on the way.
ifeq ($(os),Windows)
$(Q)$(if $(strip $(clean-dirs)), \
$(RMDIR) $(strip $(subst /,\,$(clean-dirs))))
else
$(Q)$(if $(strip $(clean-dirs)), \
for directory in $(strip $(clean-dirs)); do \
if [ -d "$$directory" ]; then \
$(RMDIR) $$directory; \
fi \
done \
)
endif
# Rebuild the project.
.PHONY: rebuild
rebuild: clean all
# Debug the project in flash.
.PHONY: debug_flash
debug_flash: all
$(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH)" -ex "reset" -readnow -se $(TARGET_FLASH)
# Debug the project in sram.
.PHONY: debug_sram
debug_sram: all
$(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM)" -ex "reset" -readnow -se $(TARGET_SRAM)
.PHONY: objfiles
objfiles: $(obj-y)
# Create object files from C source files.
$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $#) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(patsubst %/,%,$(dir $#)) || mkdir $(subst /,\,$(dir $#))
else
$(Q)test -d $(dir $#) || mkdir -p $(dir $#)
endif
#echo $(MSG_COMPILING)
$(Q)$(CC) $(c_flags) -c $< -o $#
# Create object files from C++ source files.
$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $#) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(patsubst %/,%,$(dir $#)) || mkdir $(subst /,\,$(dir $#))
else
$(Q)test -d $(dir $#) || mkdir -p $(dir $#)
endif
#echo $(MSG_COMPILING_CXX)
$(Q)$(CXX) $(cxx_flags) -c $< -o $#
# Preprocess and assemble: create object files from assembler source files.
$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk
$(Q)test -d $(dir $#) || echo $(MSG_MKDIR)
ifeq ($(os),Windows)
$(Q)test -d $(patsubst %/,%,$(dir $#)) || mkdir $(subst /,\,$(dir $#))
else
$(Q)test -d $(dir $#) || mkdir -p $(dir $#)
endif
#echo $(MSG_ASSEMBLING)
$(Q)$(CC) $(a_flags) -c $< -o $#
# Include all dependency files to add depedency to all header files in use.
include $(dep-files)
ifeq ($(target_type),lib)
# Archive object files into an archive
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
#echo $(MSG_ARCHIVING)
$(Q)$(AR) $(ar_flags) $# $(obj-y)
#echo $(MSG_SIZE)
$(Q)$(SIZE) -Bxt $#
else
ifeq ($(target_type),elf)
# Link the object files into an ELF file. Also make sure the target is rebuilt
# if the common Makefile.sam.in or project config.mk is changed.
$(target): $(linker_script) $(MAKEFILE_PATH) config.mk $(obj-y)
#echo $(MSG_LINKING)
$(Q)$(LD) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $#
#echo $(MSG_SIZE)
$(Q)$(SIZE) -Ax $#
$(Q)$(SIZE) -Bx $#
endif
endif
# Create extended function listing from target output file.
%.lss: $(target)
#echo $(MSG_EXTENDED_LISTING)
$(Q)$(OBJDUMP) -h -S $< > $#
# Create symbol table from target output file.
%.sym: $(target)
#echo $(MSG_SYMBOL_TABLE)
$(Q)$(NM) -n $< > $#
# Create Intel HEX image from ELF output file.
%.hex: $(target)
#echo $(MSG_IHEX_IMAGE)
$(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $#
# Create binary image from ELF output file.
%.bin: $(target)
#echo $(MSG_BINARY_IMAGE)
$(Q)$(OBJCOPY) -O binary $< $#
# Provide information about the detected host operating system.
.SECONDARY: info-os
info-os:
#echo $(MSG_INFO)$(os) build host detected
# Build Doxygen generated documentation.
.PHONY: doc
doc:
#echo $(MSG_GENERATING_DOC)
$(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg))
# Clean Doxygen generated documentation.
.PHONY: cleandoc
cleandoc:
#$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC))
$(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir))
# Rebuild the Doxygen generated documentation.
.PHONY: rebuilddoc
rebuilddoc: cleandoc doc
According to my calculations, your .text segment is around 4k.
Many linker applications for embedded systems, have a command or configuration file. The configuration file tells the starting addresses of segments and size.
You will need to find the configuration file and verify that the ROM section is at the correct address and has the correct capacity.
Try with -Os instead of -O3 in OPTIMIZATION flag inside config.mk; you may also use -flto -Os both when compiling and when linking (for link-time optimizations)
I finally fixed it! i've added the fno-rtti and fno-exceptions and overloaded the new, delete and destructor operator. http://www.embedded.com/design/mcus-processors-and-socs/4007134/Building-Bare-Metal-ARM-Systems-with-GNU-Part-4.
Unfortunately i cant overload the static_cast operator used in Task.h->action_helper() . Does anyone know how to solve this?
In general:
fno-exceptions is a good way to start, if you don't use it.
RTTI can also be switched off, but I think it's worth to keep. It's a really powerful feature with minimal cost.
overloading new/delete is not necessary. If you never use it and disable exceptions, it can be optimized by LTO. You have to worry about it only if you allocate dynamically.
overloading static_cast? It's "static" because it's compile time. No reason to overload it, I'm not sure if it's possible at all.
try changing debug info generation settings (-g flags in gcc)
optimize for size if possible. It makes debugging really hard.
Don't forget that all of your ASF sources are C, so setting up the C toolchain is also necessary.
Related
I am coding to the NRF51822 bluetooth chip, in Eclipse with GCC and a makefile that I maintain myself.
My problem is that every time I press build, it will compile everything, which is beginning to take quite some time. I am not that experienced in creating and maintaining make-files, so I have no idea where to start in order to get it to build incremtal instead?
My makefile is composed like this (I know there's a lot, and I haven't created this myself - found it in a tutorial, so I don't know what's relevant and what's not :-) ):
PROJECT_NAME := my_project
export OUTPUT_FILENAME
#MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
MAKEFILE_NAME := $(MAKEFILE_LIST)
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
TEMPLATE_PATH = nrf51_sdk/toolchain/gcc
ifeq ($(OS),Windows_NT)
include $(TEMPLATE_PATH)/Makefile.windows
else
include $(TEMPLATE_PATH)/Makefile.posix
endif
MK := mkdir
RM := rm -rf
#echo suspend
ifeq ("$(VERBOSE)","1")
NO_ECHO :=
else
NO_ECHO := #
endif
# Toolchain commands
CC := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc"
AS := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as"
AR := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar" -r
LD := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld"
NM := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm"
OBJDUMP := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump"
OBJCOPY := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy"
SIZE := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size"
#function for removing duplicates in a list
remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1))))
#source common to all targets
C_SOURCE_FILES += \
main.c \
file1.c \
file2.c \
file3.c \
file4.c \
#assembly files common to all targets
ASM_SOURCE_FILES = nrf51_sdk/toolchain/gcc/gcc_startup_nrf51.s
#includes common to all targets
INC_PATHS = -I Dir1/
INC_PATHS = -I Dir2
INC_PATHS += -I Dir3
INC_PATHS += -I Dir4
OBJECT_DIRECTORY = _build
LISTING_DIRECTORY =$(OBJECT_DIRECTORY)
OUTPUT_BINARY_DIRECTORY =$(OBJECT_DIRECTORY)
# Sorting removes duplicates
BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY) )
#flags common to all targets
CFLAGS = -DSOFTDEVICE_PRESENT
CFLAGS += -DNRF51
CFLAGS += -DS110
CFLAGS += -DBOARD_PCA10028
CFLAGS += -DBLE_STACK_SUPPORT_REQD
CFLAGS += -mcpu=cortex-m0
CFLAGS += -mthumb -mabi=aapcs --std=gnu99
CFLAGS += -Wall -O0 -g3
CFLAGS += -mfloat-abi=soft
# keep every function in separate section. This will allow linker to dump unused functions
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
#CFLAGS += -flto -fno-builtin
# keep every function in separate section. This will allow linker to dump unused functions
LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m0
# let linker to dump unused sections
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
LDFLAGS += --specs=nano.specs -lc -lnosys
# Assembler flags
ASMFLAGS += -x assembler-with-cpp
ASMFLAGS += -DSOFTDEVICE_PRESENT
ASMFLAGS += -DNRF51
ASMFLAGS += -DS110
ASMFLAGS += -DBOARD_PCA10028
ASMFLAGS += -DBLE_STACK_SUPPORT_REQD
#default target - first one defined
default: clean nrf51422_xxac_s110
#building all targets
all: clean
$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e cleanobj
$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e nrf51422_xxac_s110
#target for printing all targets
help:
#echo following targets are available:
#echo nrf51422_xxac_s110
#echo flash_softdevice
C_SOURCE_FILE_NAMES = $(notdir $(C_SOURCE_FILES))
C_PATHS = $(call remduplicates, $(dir $(C_SOURCE_FILES) ) )
C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILE_NAMES:.c=.o) )
ASM_SOURCE_FILE_NAMES = $(notdir $(ASM_SOURCE_FILES))
ASM_PATHS = $(call remduplicates, $(dir $(ASM_SOURCE_FILES) ))
ASM_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASM_SOURCE_FILE_NAMES:.s=.o) )
vpath %.c $(C_PATHS)
vpath %.s $(ASM_PATHS)
OBJECTS = $(C_OBJECTS) $(ASM_OBJECTS)
nrf51422_xxac_s110: OUTPUT_FILENAME := nrf51422_xxac_s110
nrf51422_xxac_s110: LINKER_SCRIPT=ble_app_hrs_gcc_nrf51.ld
nrf51422_xxac_s110: $(BUILD_DIRECTORIES) $(OBJECTS)
#echo Linking target: $(OUTPUT_FILENAME).out
$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
$(NO_ECHO)$(MAKE) -f $(MAKEFILE_NAME) -C $(MAKEFILE_DIR) -e finalize
## Create build directories
$(BUILD_DIRECTORIES):
echo $(MAKEFILE_NAME)
$(MK) $#
# Create objects from C SRC files
$(OBJECT_DIRECTORY)/%.o: %.c
#echo Compiling file: $(notdir $<)
#echo arm-none-eabi-gcc $(CFLAGS) $(INC_PATHS) -c -o $# $<
$(NO_ECHO)$(CC) $(CFLAGS) $(INC_PATHS) -c -o $# $<
# Assemble files
$(OBJECT_DIRECTORY)/%.o: %.s
#echo Compiling file: $(notdir $<)
$(NO_ECHO)$(CC) $(ASMFLAGS) $(INC_PATHS) -c -o $# $<
# Link
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(OBJECTS)
#echo Linking target: $(OUTPUT_FILENAME).out
$(NO_ECHO)$(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
## Create binary .bin file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
#echo Preparing: $(OUTPUT_FILENAME).bin
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
## Create binary .hex file from the .out file
$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
#echo Preparing: $(OUTPUT_FILENAME).hex
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
finalize: genbin genhex echosize
genbin:
#echo Preparing: $(OUTPUT_FILENAME).bin
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
## Create binary .hex file from the .out file
genhex:
#echo Preparing: $(OUTPUT_FILENAME).hex
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
echosize:
-#echo ""
$(NO_ECHO)$(SIZE) $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out
-#echo ""
clean:
$(RM) $(BUILD_DIRECTORIES)
cleanobj:
$(RM) $(BUILD_DIRECTORIES)/*.o
flash: $(MAKECMDGOALS)
#echo Flashing: $(OUTPUT_BINARY_DIRECTORY)/$<.hex
nrfjprog --reset --program $(OUTPUT_BINARY_DIRECTORY)/$<.hex)
## Flash softdevice
flash_softdevice:
#echo Flashing: s110_softdevice.hex
nrfjprog --reset --program nrf51_sdk/softdevice/s110/hex/s110_softdevice.hex
all: clean
check this line. The default (first) Target of your Makefile depends on clean, so before any build is started, the clean target is executed that likely will remove all built files, to rebuild them.
Drop the clean and you should get the incremental behaviour make was designed for.
IntermediateRobotFunctions.cpp:
/*
* IntermediateRobotFunctions.cpp
*
* Created on: 27 Mar 2015
* Author: Edward
*/
#include "IntermediateRobotFunctions.hpp"
IntermediateRobotFunctions::IntermediateRobotFunctions() {
block = Block::Block();
robot = Robot::Robot();
basic = BasicRobotFunctions::BasicRobotFunctions();
carrying = false;
}
IntermediateRobotFunctions::IntermediateRobotFunctions(Robot R,Block B) {
block = B;
robot = R;
basic = BasicRobotFunctions::BasicRobotFunctions(R);
carrying = false;
}
IntermediateRobotFunctions::~IntermediateRobotFunctions() {}
void IntermediateRobotFunctions::PickUp(Robot R, Block B){
if(R.getCarrying()==false){
Walk(R);
basic.MoveChest();
basic.MoveArm(1);
basic.MoveArm(2);
basic.MoveChest();
R.setCarrying(true);
carrying = true;
}
else{
PutDown(R);
PickUp(R,B);
}
}
void IntermediateRobotFunctions::PutDown(Robot R){
if(R.getCarrying()==true){
basic.MoveChest();
basic.MoveArm(1);
basic.MoveArm(2);
basic.MoveChest();
R.setCarrying(false);
carrying = false;
}
}
//TODO to test
Block IntermediateRobotFunctions::newNearest(){
Block B,B1;
B1 = Block::Block();
for(int i = 0; i<360; i++){
basic.Turn(1);
if(dxl_read_word(100,32)>0){
B = Block::Block();
B.setDistance(dxl_read_word(100,27));
B.setBrightness(dxl_read_word(100,30));
B.setGrounded(true);
}
if(B.getDistance() <= B1.getDistance()){
B1 = B;
}
}
return B1;
}
Robot IntermediateRobotFunctions::updateRobotData(){
Block block;
bool carry = carrying;
block = newNearest(robot);
Robot R = Robot(block,carry);
return R;
}
//TODO to test
void IntermediateRobotFunctions::Walk(Robot R){
int steps = basic.CalculateSteps();
while(dxl_read_word(100,32)<=0)
basic.Turn(1);
for(int i =0;i<steps;i++){
basic.Step(1);
basic.Step(2);
}
}
IntermediateRobotFunctions.hpp:
/*
* IntermediateRobotFunctions.hpp
*
* Created on: 27 Mar 2015
* Author: Edward
*/
#ifndef INTERMEDIATEROBOTFUNCTIONS_HPP_
#define INTERMEDIATEROBOTFUNCTIONS_HPP_
#include "typedefinitions.h"
#include "Robot.hpp"
#include "Block.hpp"
#include "BasicRobotFunctions.hpp"
class IntermediateRobotFunctions {
public:
static Block block;
static Robot robot;
static BasicRobotFunctions basic;
static bool carrying;
//pos position;
static void PickUp(Robot R, Block B);
static void PutDown(Robot R);
static void Walk(Robot R);
static Block newNearest(Robot R);
static Block newNearest();
static Robot updateRobotData();
IntermediateRobotFunctions();
IntermediateRobotFunctions(Robot R,Block B);
virtual ~IntermediateRobotFunctions();
};
#endif /* INTERMEDIATEROBOTFUNCTIONS_HPP_ */
Makefile:
# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
# Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
# with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
# bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------
# MCU name
MCU = atmega128
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
# Typical values are:
# F_CPU = 1000000
# F_CPU = 1843200
# F_CPU = 2000000
# F_CPU = 3686400
# F_CPU = 4000000
# F_CPU = 7372800
# F_CPU = 8000000
# F_CPU = 11059200
# F_CPU = 14745600
# F_CPU = 16000000
# F_CPU = 18432000
# F_CPU = 20000000
F_CPU = 16000000
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
# Target file name (without extension).
TARGET = main
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# List C source files here. (C dependencies are automatically generated.)
SRC =
# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC = $(TARGET).cpp AdvancedRobotFunctions.cpp IntermediateRobotFunctions.cpp BasicRobotFunctions.cpp Robot.cpp Block.cpp Structure.cpp
# List Assembler source files here.
# Make them always end in a capital .S. Files ending in a lowercase .s
# will not be considered source files but generated files (assembler
# output from the compiler), and will be deleted upon "make clean"!
# Even though the DOS/Win* filesystem matches both .s and .S the same,
# it will preserve the spelling of the filenames, and gcc itself does
# care about how the name is spelled on its command-line.
ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
# AVR Studio 4.10 requires dwarf-2.
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2
# List any extra directories to look for include files here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99
# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)
# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS
#---------------- Compiler Options C ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
#---------------- Compiler Options C++ ----------------
# -g*: generate debugging information
# -O*: optimization level
# -f...: tuning, see GCC manual and avr-libc documentation
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CPPFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CPPFLAGS += $(CSTANDARD)
#---------------- Assembler Options ----------------
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns: create listing
# -gstabs: have the assembler create line number information; note that
# for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)
MATH_LIB = -lm
# List any extra directories to look for libraries here.
# Each directory must be seperated by a space.
# Use forward slashes for directory separators.
# For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =
#---------------- External Memory Options ----------------
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
#---------------- Linker Options ----------------
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x
#---------------- Programming Options (avrdude) ----------------
# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500v2
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com3 # programmer connected to serial device
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242
# Debugging host used to communicate between GDB / avarice / simulavr, normally
# just set to localhost unless doing some sort of crazy debugging when
# avarice is running on a different computer.
DEBUG_HOST = localhost
#============================================================================
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin --------
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:
# Define all object files.
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
# Compiler flags to generate dependency files.
GENDEPFLAGS = -MMD -MP -MF .dep/$(#F).d
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target.
all: begin gccversion sizebefore build sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)
# Eye candy.
# AVR Studio 3.x does not check make's exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
#echo
#echo $(MSG_BEGIN)
end:
#echo $(MSG_END)
#echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
sizebefore:
#if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
#if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi
# Display compiler version information.
gccversion :
#$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Generate avr-gdb config/init file which does the following:
# define the reset signal, load the target file, connect to target, and set
# a breakpoint at main().
gdb-config:
#$(REMOVE) $(GDBINIT_FILE)
#echo define reset >> $(GDBINIT_FILE)
#echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
#echo end >> $(GDBINIT_FILE)
#echo file $(TARGET).elf >> $(GDBINIT_FILE)
#echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
#echo load >> $(GDBINIT_FILE)
endif
#echo break main >> $(GDBINIT_FILE)
debug: gdb-config $(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
#echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
#$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
#$(WINSHELL) /c pause
else
#$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
#$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000
coff: $(TARGET).elf
#echo
#echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
#echo
#echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
#echo
#echo $(MSG_FLASH) $#
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $#
%.eep: %.elf
#echo
#echo $(MSG_EEPROM) $#
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $# || exit 0
# Create extended listing file from ELF output file.
%.lss: %.elf
#echo
#echo $(MSG_EXTENDED_LISTING) $#
$(OBJDUMP) -h -S -z $< > $#
# Create a symbol table from ELF output file.
%.sym: %.elf
#echo
#echo $(MSG_SYMBOL_TABLE) $#
$(NM) -n $< > $#
# Create library from object files.
.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
#echo
#echo $#
#echo $(MSG_CREATING_LIBRARY) $#
$(AR) $# $(OBJ)
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
#echo
#echo $(MSG_LINKING) $#
$(CC) $(ALL_CFLAGS) $^ --output $# $(LDFLAGS)
# Compile: create object files from C source files.
$(OBJDIR)/%.o : %.c
#echo
#echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $#
# Compile: create object files from C++ source files.
$(OBJDIR)/%.o : %.cpp
#echo
#echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $#
# Compile: create assembler files from C source files.
%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $#
# Compile: create assembler files from C++ source files.
%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $#
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
#echo
#echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $#
# Create preprocessed source for use in sending a bug report.
%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $#
# Target: clean project.
clean: begin clean_list end
clean_list :
#echo
#echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep
# Create object files directory
$(shell mkdir $(OBJDIR) 2>/dev/null)
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config
First of all I would like to apologize for the length of the code.
I've been getting errors in my Makefile stating that the "block", "robot", "basic", and "carrying" variables called in the constructors and in various methods in this source file have undefined references to their header file definitions
The errors are as follows:
IntermediateRobotFunctions.o: In function `IntermediateRobotFunctions::updateRobotData()':
C:\Users\Edward\CWork\BioloidAVR_/IntermediateRobotFunctions.cpp:74: undefined reference to `IntermediateRobotFunctions::carrying'
C:\Users\Edward\CWork\BioloidAVR_/IntermediateRobotFunctions.cpp:75: undefined reference to `IntermediateRobotFunctions::robot'
C:\Users\Edward\CWork\BioloidAVR_/IntermediateRobotFunctions.cpp:75: undefined reference to `IntermediateRobotFunctions::robot'
C:\Users\Edward\CWork\BioloidAVR_/IntermediateRobotFunctions.cpp:75: undefined reference to `IntermediateRobotFunctions::newNearest(Robot)'
where the above errors are repeated for all variables in every method of all of the following classes:
BasicRobotFunctions
IntermediateRobotFunctions
AdvancedRobotFunctions
Robot
Block
Structure
including on variables and methods received from pre-made source and header files imported from the Bioloid Embedded C API.
Again apologies for a long post possibly including a little irrelevant information but I wanted to give the complete picture; can anyone please tell me what's wrong and how I should go about fixing it?
You have this:
class IntermediateRobotFunctions {
public:
static Block block;
static Robot robot;
static BasicRobotFunctions basic;
static bool carrying;
where you have declared these variables to be static, but you have not put this:
Block IntermediateRobotFunctions::block;
Robot IntermediateRobotFunctions::robot;
BasicRobotFunctions IntermediateRobotFunctions::basic;
bool IntermediateRobotFunctions::carrying;
any place in your .cpp files, which means you have not actually defined (set aside actual memory for) those variables anywhere. That's what the compiler messages are telling you - the variables can't be found when it's trying to fix up all the various address links...
hen I do make clean it complains about missing files. In particular it complains about mapnameserver.hthat is included in nstest.cc and nstime.cc.
I thought that doing make clean would ignore all other targets, even implicit ones.
What I want is to be able to do make clean and make vectornameserver without make complaining about the headers that nstest.cc and nstime.cc includes that I have not yet written. Is this possible?
Below is the files in the src dir
nameserverinterface.h
nstest.cc
nstime.cc
vectornameserver.cc
vectornameserver.h
And this is the Makefile
#
# Makefile for CPP
#
# Compiler and compiler options:
CC = /usr/local/bin/clang++
CXX = /usr/local/bin/clang++
CXXFLAGS = -c -pipe -O2 -Wall -W -ansi -pedantic-errors
CXXFLAGS += -Wmissing-braces -Wparentheses -Wold-style-cast
CXXFLAGS += -std=c++11 -stdlib=libc++ -nostdinc++
CXXFLAGS += -I/Users/einar/devel/libcxx/include/
LDFLAGS = -stdlib=libc++
LDLIBS = -L/Users/einar/devel/libcxx/lib/
SRCDIR = ../src
LIBDIR = ../lib
BINDIR = ../bin
DEPDIR = ../dep
VPATH = $(SRCDIR):$(LIBDIR):$(BINDIR):$(DEPDIR)
LIB_INSTALL =
BIN_INSTALL =
SRC = $(wildcard $(SRCDIR)/*.cc)
OBJ = $(notdir $(SRC:.cc=.o))
DEP = $(addprefix $(DEPDIR)/, $(notdir $(SRC:.cc=.d)))
PROGS = vectornameserver
MAKEDEPEND = $(CXX) -MM $(CPPFLAGS) -o $*.d $<
CP = /bin/cp
###
#
# Phony targets
#
###
.PHONY: all
all: $(PROGS)
.PHONY: folder_setup
folder_setup:
mkdir -p $(SRCDIR)
mkdir -p $(LIBDIR)
mkdir -p $(BINDIR)
mkdir -p $(DEPDIR)
.PHONY: clean
clean:
#$(RM) $(OBJ)
.PHONY: cleaner
cleaner:
#$(RM) $(OBJ)
#$(RM) $(PROGS)
#$(RM) $(DEP)
#$(RM) $(wildcard $(DEPDIR)/*.d*)
###
#
# Set up targets for program files in this section
# a rule should look like:
# program: obj1.o obj2.o ...
#
###
vectornameserver : vectornameserver.o
###
#
# In this section automatic dependencies are handled.
#
###
$(addprefix $(DEPDIR)/, %.d): %.cc
#set -e; rm -f $#; \
$(CXX) -MM $(CPPFLAGS) $< > $#.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $#: ,g' < $#.$$$$ \
> $#; rm -f $#.$$$$
###
#
# Include the automatically generated dependency files
#
###
include $(DEP)
Thanks in advance.
The problem is that you have an include directive in the makefile. This implicitly makes all the included dependency files implicit targets that must be refreshed BEFORE the primary target can be run. It is those rules that are running the compiler and giving you the errors.
Since generally you don't want/need the dependency files if you're just doing a make clean, the usual thing is to wrap appropriate ifs around the include:
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),cleaner)
-include $(DEP)
endif
endif
This will avoid trying to include the depfiles (and thus regenerate them) if you do make clean or make cleaner. In addition, the - prefix on the include supresses warnings about the depfiles not existing when you first run make (it will (re)generate them and reread the makefile and depfiles if need be.)
I am not very familiar with make; i've always used and modified this highly ancient makefile I inherited from another project, modifying it as necessary. Up until now, it has functioned perfectly, compiling together projects with 20-50 files, even within sub-directories, determining and building all the dependencies properly.
Today I am running a very simple test code to determine if BOOST.MPI will work on a cluster I recently got access to. I am trying to compile a 1-file test case to make sure that the library works. This is also my first time building and linking to boost on this system.
I have boost installed in my user directory: ~/boost, and I've run the appropriate bjam to ensure that BOOST.MPI is present. I don't believe my problem lies there. As you'll see in a moment, however, I had to include -lboost_mpi and -lboost_serialization to get as far as I did.
The makefile seems to compile, and assemble just fine producing the intermediary .a file. It hangs up on the linking step with a surprising error:
Creating dependency for "boosttest.cpp"
Compiling "boosttest.cpp"
Assembling ag...
ar: creating ./libag.a
Linking bt1...
/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [bt1] Error 1
The only source code I've written (copy/pasted right out of the Boost.MPI implementation page):
boosttest.cpp:
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <iostream>
int main(int argc, char* argv[])
{
boost::mpi::environment env(argc, argv);
boost::mpi::communicator world;
std::cout << "I am process " << world.rank() << " of " << world.size()<< "." << std::endl;
return 0;
}
Now for the part where I get lost. This is the makefile I've modified. I mostly understand what parts of it are doing, and it is the only makefile I've ever seen (although as mentioned I'm not very experienced with them) to produce .d files containing a list of all dependent libraries.
Makefile:
PROJECT = boosttest
# The names of the sub-projects that the executable depends on. These names are used later on to define targets, location, libraries, etc.
DEPS =
# The names of the sub-projects that the test executable depends on.
TEST_DEPS =
EXE_DEPS =
LOCAL_O_FILES = boosttest.o
LOCAL_TEST_O_FILES =
LOCAL_LIB_NAME = ag
LOCAL_LIB_DIR = .
LOCAL_TEST_LIB_NAME =
LOCAL_TEST_LIB_DIR =
LOCAL_INCLUDE_ROOT = .
EXE_NAME = BT
MPIC_DIR = /usr/local/mvapich2-1.6-gcc/
#these assume our local path and bin are set up properly since I don't know where the compilers are
CC = $(MPIC_DIR)/bin/mpicc
CCC = $(MPIC_DIR)/bin/mpicxx
F77 = $(MPIC_DIR)/bin/mpif77
CLINKER = $(MPIC_DIR)/bin/mpicc
CCLINKER = $(MPIC_DIR)/bin/mpicxx
FLINKER = $(MPIC_DIR)/bin/mpif90
F90 = $(MPIC_DIR)/bin/mpif90
F90LINKER = $(MPIC_DIR)/bin/mpif90
MAKE = make --no-print-directory
SHELL = /bin/sh
#PROF = -ggdb -O2
PROF = -O2
ADDITIONAL_LIBS = -lboost_mpi -lboost_serialization
SED = $(shell which sed)
GREP = $(shell which grep)
# Warnings will depend on the GCC version -- if it's 4, have "-Wdeclaration-after-statement -Wunused-value -Wunused-variable"
#GCC_MAJOR_VERSION = $(shell $(CCC) --version | $(GREP) "\(egcs\|gcc\)" | $(SED) "s/[^0-9]*\([0-9]\).*/\1/")
#WARNINGS = -Wno-import $(shell if test $(GCC_MAJOR_VERSION) -eq 4; then echo -Wunused-value -Wunused-variable; fi)
#GCC_INSTALL_DIR = /turing/software-linux/mpich-eth
GCC_INSTALL_DIR = $(MPIC_DIR)
GCC_INCLUDE_DIR = $(GCC_INSTALL_DIR)/include/
GCC_LIB_DIR = $(GCC_INSTALL_DIR)/lib/
BOOST_DIR = ~/boost
BOOST_LIB_DIR = ~/boost/stage/lib
# Expand SRCDIR so that it turns into "-I <srcdir>" for each listed directory
INCLUDE_DIRS = -I $(OBJC_ROOT)/include $(foreach dep, $(UNIQUE_DEPS), -I$($(dep)_INCLUDE_ROOT)) -I $(LOCAL_INCLUDE_ROOT) -I $(BOOST_DIR) -I $(GCC_INCLUDE_DIR)
#C_FLAGS = -DROM $(PROF) $(WARNINGS) $(INCLUDE_DIRS)
C_FLAGS = -DROM $(PROF) $(INCLUDE_DIRS)
L_FLAGS = $(foreach dir, $(OBJC_ROOT) $(DEP_LIB_DIRS), -L$(dir)) -L $(BOOST_LIB_DIR) -L $(GCC_LIB_DIR) $(PROF) $(ADDITIONAL_LIBS)
TEST_L_FLAGS = $(foreach dir, $(OBJC_ROOT) $(TEST_DEP_LIB_DIRS), -L$(dir)) -L/usr/lib -Xlinker --whole-archive $(TEST_REQUIRED_LIBS) -Xlinker --no-whole-archive
REQUIRED_LIBS = $(foreach dep, $(DEPS) LOCAL, $(if $($(dep)_LIB_NAME), -l$($(dep)_LIB_NAME)))
TEST_REQUIRED_LIBS = $(foreach dep, $(TEST_DEPS) LOCAL LOCAL_TEST, $(if $($(dep)_LIB_NAME), -l$($(dep)_LIB_NAME)))
.SUFFIXES:
.SUFFIXES: .d .cc .cpp .c .o
ASSEMBLE_TARGETS = $(foreach dep,$(DEPS),$(dep)_LIB_NAME)
ASSEMBLE_TEST_TARGETS = $(foreach dep,$(TEST_DEPS),$(dep)_LIB_NAME)
CLEAN_TARGETS = $(foreach dep, $(UNIQUE_DEPS), $(dep)_CLEAN)
LOCAL_D_FILES = $(LOCAL_O_FILES:.o=.d)
LOCAL_TEST_D_FILES = $(LOCAL_TEST_O_FILES:.o=.d) $(TEST_RUNNER:.o=.d)
DEP_LIB_DIRS = $(foreach dep, $(DEPS) LOCAL, $($(dep)_LIB_DIR))
TEST_DEP_LIB_DIRS = $(foreach dep, $(TEST_DEPS) LOCAL LOCAL_TEST, $($(dep)_LIB_DIR))
UNIQUE_ASSEMBLE_TARGETS = $(sort $(ASSEMBLE_TARGETS) $(ASSEMBLE_TEST_TARGETS))
UNIQUE_DEPS = $(sort $(DEPS) $(TEST_DEPS))
LOCAL_LIB = $(if $(LOCAL_LIB_NAME), $(LOCAL_LIB_DIR)/lib$(LOCAL_LIB_NAME).a)
LOCAL_TEST_LIB = $(if $(LOCAL_TEST_LIB_NAME), $(LOCAL_TEST_LIB_DIR)/lib$(LOCAL_TEST_LIB_NAME).a)
EXE_TARGETS = $(foreach dep,$(EXE_DEPS),$(dep)_EXE_NAME)
INSTALL_TARGETS = $(foreach dep,$(EXE_DEPS),$(dep)_INSTALL)
export PROJECTS += $(PROJECT)
# PHONY targets get remade even if there exists an up-to-date file with the same name.
.PHONY: default clean compile assemble link submit
# Targets for mortals
default: link
clean: $(CLEAN_TARGETS) LOCAL_CLEAN
compile: $(DEPS) $(LOCAL_D_FILES) $(LOCAL_O_FILES)
assemble: compile $(ASSEMBLE_TARGETS) $(LOCAL_LIB)
link: assemble $(EXE_TARGETS) $(EXE_NAME)
install: $(INSTALL_TARGETS) $(if $(EXE_NAME), LOCAL_INSTALL)
submit: link
qsub $(PROJECT).qsub
# Targets for make
# Invoking sub projects
$(UNIQUE_DEPS): MAKE_TARGET = $(if $(filter %_TEST, $#), compile-tests, compile)
$(UNIQUE_DEPS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($#_DIR) && $(MAKE) $(MAKE_TARGET))
# First, remove the _LIB_NAME attached by ASSEMBLE_TARGETS, a
$(UNIQUE_ASSEMBLE_TARGETS): DEP_NAME = $(#:_LIB_NAME=)
$(UNIQUE_ASSEMBLE_TARGETS): MAKE_TARGET = $(if $(filter %_TEST, $(DEP_NAME)), assemble-tests, assemble)
$(UNIQUE_ASSEMBLE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) $(MAKE_TARGET))
# First, remove the _EXE_NAME attached by EXE_TARGETS, a
$(EXE_TARGETS): DEP_NAME = $(#:_EXE_NAME=)
$(EXE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) link)
$(CLEAN_TARGETS): DEP_NAME = $(#:_CLEAN=)
$(CLEAN_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) clean)
$(INSTALL_TARGETS): DEP_NAME = $(#:_INSTALL=)
$(INSTALL_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) install)
#Local stuff
# The rule to change either a '.c' or a '.m' to a '.o'
#%.o : %.c %.d %.cc %.cpp
.cc.o .cpp.o .c.o:
#echo "Compiling \"$<\""
#$(CCC) -c $(C_FLAGS) $< -o $#
.cc.d .cpp.d .c.d :
#echo "Creating dependency for \"$<\""
# #$(CCC) $(WARNINGS) $(INCLUDE_DIRS) -MM $< -o $#
# This foogly hack because gcc seems to have issues with emitting the correct target/dependency names of
# files in sub-dirs of the current dir (specifically, it doesn't add the sub-dir to the target
# name, and insists on adding the directory to the dependencies) which ends up breaking dependencies...)
#dependLine=$$( $(CCC) $(C_FLAGS) $(INCLUDE_DIRS) -MM $< ); \
dirName=$$( dirname $< | $(SED) "s/\//\\\\\//g" ); \
dependLine=$$( echo $${dependLine} | $(SED) "s/ $${dirName}\// /g" ); \
oFile=$$( echo $${dependLine} | $(SED) "s/:.*//" ); \
dependencies=$$( echo $${dependLine} | $(SED) "s/.*://" ); \
echo $${oFile} $${oFile%.o}.d: $${dependencies} | $(SED) "s/ \\\//g" > $#
$(UNIQUE_ASSEMBLE_TARGETS): DEP_NAME = $(#:_LIB_NAME=)
$(UNIQUE_ASSEMBLE_TARGETS): MAKE_TARGET = $(if $(filter %_TEST, $(DEP_NAME)), assemble-tests, assemble)
$(UNIQUE_ASSEMBLE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) $(MAKE_TARGET))
# First, remove the _EXE_NAME attached by EXE_TARGETS, a
$(EXE_TARGETS): DEP_NAME = $(#:_EXE_NAME=)
$(EXE_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) link)
$(CLEAN_TARGETS): DEP_NAME = $(#:_CLEAN=)
$(CLEAN_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) clean)
$(INSTALL_TARGETS): DEP_NAME = $(#:_INSTALL=)
$(INSTALL_TARGETS):
$(if $(findstring $(DEP_NAME), $(PROJECTS)),,cd $($(DEP_NAME)_DIR) && $(MAKE) install)
#Local stuff
# The rule to change either a '.c' or a '.m' to a '.o'
#%.o : %.c %.d %.cc %.cpp
.cc.o .cpp.o .c.o:
#echo "Compiling \"$<\""
#$(CCC) -c $(C_FLAGS) $< -o $#
.cc.d .cpp.d .c.d :
#echo "Creating dependency for \"$<\""
# #$(CCC) $(WARNINGS) $(INCLUDE_DIRS) -MM $< -o $#
# This foogly hack because gcc seems to have issues with emitting the correct target/dependency names of
# files in sub-dirs of the current dir (specifically, it doesn't add the sub-dir to the target
# name, and insists on adding the directory to the dependencies) which ends up breaking dependencies...)
#dependLine=$$( $(CCC) $(C_FLAGS) $(INCLUDE_DIRS) -MM $< ); \
dirName=$$( dirname $< | $(SED) "s/\//\\\\\//g" ); \
dependLine=$$( echo $${dependLine} | $(SED) "s/ $${dirName}\// /g" ); \
oFile=$$( echo $${dependLine} | $(SED) "s/:.*//" ); \
dependencies=$$( echo $${dependLine} | $(SED) "s/.*://" ); \
echo $${oFile} $${oFile%.o}.d: $${dependencies} | $(SED) "s/ \\\//g" > $#
$(LOCAL_LIB): compile $(ASSEMBLE_TARGETS)
#echo Assembling $(LOCAL_LIB_NAME)...
#ar rs $(LOCAL_LIB) $(LOCAL_O_FILES)
# Create the executable
$(EXE_NAME): assemble
#echo Linking $(EXE_NAME)...
#$(CCC) -o $(EXE_NAME) $(L_FLAGS)
# Erase all object files, the dependencies file, the core file and the executable, then rebuild everything
LOCAL_CLEAN:
#echo Cleaning $(PROJECT)...
#rm -f $(LOCAL_O_FILES) $(LOCAL_TEST_O_FILES) $(LOCAL_LIB) $(LOCAL_TEST_LIB) $(EXE_NAME) $(TEST_EXE_NAME) $(LOCAL_D_FILES) $(LOCAL_TEST_D_FILES) $(TEST_RUNNER) $(TEST_RUNNER:.o=.d) core*
ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include $(LOCAL_O_FILES:.o=.d) $(LOCAL_TEST_O_FILES:.o=.d)
endif
The paths to my mpicxx compiler (needed for the cluster, and for those unfamiliar, it wraps gcc) are correct, as evidenced by the fact that it does compile, it just won't link. Similarly, my boost library paths seem functional, the -lboost_mpi flag gets caught properly.
At this point, my question has extended to be for my own education based on how this makefile works/intends to work. Ultimately the entirely obvious/simple command:
mpicxx boosttest.cpp -L ~/boost/stage/lib/ -lboost_mpi -lboost_serialization -o test
however I want to get a proper makefile going as once I get past this test case verifying Boost.MPI's equivalent of a hello world, I'll be moving on to projects involving my full source code, 20+ files with cross dependencies, etc. Any help or intuition would be greatly appreciated.
Based on the suggestion of #Oktalist above, I was able to find something that works, at least for the single-file case, but I can't see why it won't work when I extend this to multiple files. I'm still at a loss why this worked in the past but not now, but perhaps I changed something I wasn't tracking.
The correction is near the end, in this block:
# Create the executable
$(EXE_NAME): assemble
#echo Linking $(EXE_NAME)...
#$(CCC) $(L_FLAGS) $(LOCAL_LIB) -o $(EXE_NAME)
I'm trying to run ORTS on my Mac for a school project. It was ostensibly written to be cross-platform, but I don't know if it was ever properly tested on OSX. After a great deal of difficulty, I managed to get it to compile, but it still doesn't quite work.
When I run the ortsg application, which is the OpenGL graphical interface, the terminal output indicates that the game starts up, loads its assets and runs correctly. However, the actual game window never appears. The only possible indication of any problem is the following message:
2011-11-23 16:52:33.513 ortsg[4565:107] GLUT Warning: glutInit being called a second time.
Other than that message, all of the output is exactly the same as what I see when running on my school's Slackware Linux machines, where the game runs fine. (Unfortunately it's rather inconvenient for me to do my work on those machines, hence my attempts to run it on OSX.) I can get rid of that warning by commenting out a call to glutInit in apps/ortsg/src/ortsg_main.C, which doesn't seem to introduce any other problems, but the game window is still never shown.
I can't seem to find reports of anyone having similar problems on Google. I don't expect anyone on SO will be intimately familiar with ORTS, so my questions are as follows:
Are there any common scenarios which might cause a GLUT window to not appear, particularly on OSX?
Does GLUT provide any facilities for debugging such problems?
Edit: As requested by JimN, here is some of the GLUT initialization code...
// From apps/ortsg/src/ortsg_main.C
int main(int argc, char **argv)
{
char mydir[81];
getcwd(mydir, 80);
glutInit(&argc, argv);
chdir(mydir);
// ...
}
// From libs/gfxclient/src/GfxInit.C
void glutVisibilityDebug(int state)
{
if(state == GLUT_VISIBLE)
cout << "Window is visible" << endl;
else if(state == GLUT_NOT_VISIBLE)
cout << "Window is invisible" << endl;
else
cout << "Window state unknown";
}
void GfxModule::init_GLUT_window()
{
cerr << "INITIALIZE GLUT WINDOW" << endl;
GfxGlutAdaptor::set_client(this);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA);
// the window starts near the upper left corner of the screen
glutInitWindowPosition(opt.win_x, opt.win_y);
glutInitWindowSize(opt.win_w, opt.win_h);
// Open a window
glutCreateWindow(opt.title.c_str());
// Register the splash as the draw routing until
glutDisplayFunc (GfxGlutAdaptor::splash);
glutVisibilityFunc(glutVisibilityDebug);
if (opt.full_screen) glutFullScreen();
}
I added the glutVisibilityDebug function to see if I could determine what GLUT thinks the window's visibility state is, but none of my debug statements are ever printed. Something else just occurred to me which might help debug this. I tried at one point to replace glutDisplayFunc with a function which just printed "glutDislplayFunc called" to stderr. I noticed that the text was only printed when I quit the application.
I downloaded the daily snapshot from 26/11/2011, and then installed all dependencies using brew on my Mac.
Executed export OSTYPE=DARWIN followed by make init and make. There were several compilation problems which I fixed on this makefile:
# $Id: makefile 10648 2011-10-06 15:46:07Z mburo $
#
# This is an ORTS file (c) Michael Buro, licensed under the GPL
# This make file works for systems which use gcc
#
# - shell variable OSTYPE must be set in your shell rc file as follows:
#
# if LINUX matches uppercase($OSTYPE) => Linux
# if DARWIN matches => Mac OS X
# if CYGWIN matches => Cygwin (gcc on Windows)
# if MSYS matches => MinGW (gcc on Windows)
#
# check that value with echo $OSTYPE and set it in your shell resource
# file if above words don't match. Don't forget export OSTYPE when using sh or bash
#
# I use: OSTYPE=`uname`
#
# - ORTS_MTUNE = i686 athlon-xp pentium-m etc.
# if set, -mtune=$(ORTS_MTUNE) is added to compiler options
#
# - set GCC_PRECOMP to 1 if you want to use precompiled header files (gcc >= 3.4)
#
# - adjust SDL/X paths if necessary
#
# - for non-gcc compilers try -DHAS_TYPEOF=0 if typeof causes trouble
#
# - make MDBG=1 ... displays the entire compiler/linker invocation lines
#
# - make clean removes make generated files
# - make cleanobj removes all .o files
#
# - make [MODE=dbg] compiles targets in debug mode (no STL debug!)
#
# - make MODE=opt compiles with optimizations
#
# - make MODE=bp compiles with bprof info
#
# - make MODE=gprof compiles with gprof info
#
# - make MODE=stldbg compiles optimized stl debug version
#
# - make <app> creates application bin/<app> (omit prefix bin/ !)
# use periods in <app> in place of slashes for applications
# within subdirectories (e.g. "make rtscomp06.game2.simtest")
#
# - make list displays a list of all registered applications
#
# - make init creates necessary dep+bin+obj directories and links
#
# - make creates all applications
#
# - shell variable ORTS_MODE defines the default compile mode
# if not set, the passed MODE= parameter or dbg will be used, if MODE is not passed
# otherwise ORTS_MODE will be used
#
# issues:
#
# - all include files are used (only using library includes would be better)
#
# new:
#
# applications and libraries can now name their individual external library dependencies
# (libs + headers)
# see: apps/*/src/app.mk and libs/*/src/lib.mk, esp. libs/gfxclient/src/lib.mk
#
# todo: adjust mac/cygwin to new libary setting
# supported substrings of OSTYPE
# The following words must be uppercase
# If they are found in the uppercased OSTYPE variable
# the particular O/S matches
OSTYPE_LINUX := LINUX
OSTYPE_MAC := DARWIN
OSTYPE_CYGWIN := CYGWIN
OSTYPE_MINGW := MSYS
# convert OSTYPE to uppercase
OSTYPE := $(shell echo -n "$(OSTYPE)" | tr a-z A-Z )
#$(warning OSTYPE=$(OSTYPE))
#OSTYPE := LINUX
# -DOS_LINUX or -DOS_MAC or -DOS_CYGWIN is passed to g++
# also set: OS_LINUX, OS_CYGWIN, OS_MAC := 1 resp.
# MinGW uses OS_LINUX for now.
# tar file name
PROJ := orts
# directories to be excluded from snapshot tar file
# no longer needed SNAPSHOT_EXCLUDE := libs/mapabstr apps/mapabs apps/polypath apps/hpastar
# special targets
EXCL_INC := clean init cleanobj tar dep rmdeps list tar snapshot rpm
# libraries
#LIB_DIRS := kernel network serverclient gfxclient pathfind osl mapabstr path ortsnet ai/low dcdt/se dcdt/sr newpath
#LIB_DIRS := $(wildcard libs/*) libs/dcdt/se libs/dcdt/sr libs/ai/low
LIB_DIRS := $(wildcard libs/*/src) $(wildcard libs/*/*/src)
#$(warning LIBS $(LIB_DIRS))
# sub-projects
ifeq ("$(MAKECMDGOALS)","")
APP_DIRS := orts ortsg# built by default (do not edit)
else
APP_DIRS := $(MAKECMDGOALS)# build the passed on application
endif
FILT := $(filter $(EXCL_INC),$(MAKECMDGOALS))
ifneq ("$(FILT)","")
APP_DIRS :=
endif
#MAKECMDGOALS := compile_gch link_gch $(MAKECMDGOALS)
#$(warning making $(MAKECMDGOALS) ...)
# $(warning making $(APP_DIRS) ...)
.PHONY: all ALWAYS $(EXCL_INC) $(APP_DIRS) init
# where dependencies are stored (change also in dependency command (***) below)
#
DEP := dep
#$(error $(vp))
# make libraries and applications, make and link gch file first
all: all_end
# create tar file of the entire project
tar:
# $(MAKE) clean; cd ..; tar cfz ../$(PROJ).tgz $(PROJ)
# daily SVN snapshot
SVNROOT=svn://mburo#bodo1.cs.ualberta.ca:/all/pubsoft
snapshot:
rm -rf orts
mkdir orts
svn export $(SVNROOT)/orts/trunk orts/trunk
tar cfz $(PROJ).tgz orts
rm -rf orts
rm -rf orts_data
mkdir orts_data
svn export $(SVNROOT)/orts_data/trunk orts_data/trunk
tar cfz orts_data.tgz orts_data
rm -rf orts_data
CC := g++
CC_OPTS := -pipe -felide-constructors -fstrict-aliasing -Wno-deprecated
# -fno-merge-constants
#WARN := -Wall -W -Wundef
WARN := -Wall -W
#-Wold-style-cast
#ifneq ("$(OSTYPE)", "$(OSTYPE_MINGW)")
ifeq (,$(findstring $(OSTYPE_MINGW),$(OSTYPE)))
WARN += -Wundef
endif
OPT:=-O3
ifneq ("$(ORTS_MTUNE)","")
OPT:=$(OPT) -mtune=$(ORTS_MTUNE)
endif
OPT_FRAME := -fomit-frame-pointer
# default
AWK := gawk
EXE_SUFFIX :=
#ifeq ("$(OSTYPE)", "$(OSTYPE_MAC)")
ifneq (,$(findstring $(OSTYPE_MAC),$(OSTYPE)))
################### Mac OS X
OS_MAC := 1
MACROS := -DGCC -DOS_MAC -DHAS_TYPEOF=1 -DTRANSFORM_MOUSE_Y=0 -DMAC_OS_X_VERSION_MIN_REQUIRED=1040 -DTARGET_API_MAC_CARBON=1
USR_FRAME := /Library/Frameworks
SYS_FRAME := /System/Library/Frameworks
INC_OPTS += -I/usr/local/Cellar/sdl/1.2.14/include/SDL \
-I/usr/local/Cellar/sdl_net/1.2.7/include/SDL \
-I/usr/local/Cellar/glew/1.7.0/include/GL \
-I/usr/include/GL \
-L$(USR_FRAME) -L$(SYS_FRAME) -L/usr/local/Cellar/sdl/1.2.14/lib -L/usr/local/Cellar/sdl_net/1.2.7/lib -L/usr/local/lib
SHARED_LIBS0 := -lc -lz -lpthread \
-lSDL \
-lSDL_net \
-lSDLmain \
-framework Foundation \
-framework AppKit
AWK := awk
#WARN += -Wno-long-double
ifeq ("$(CPU)", "G5")
OPT += -mcpu=970 -mpowerpc64
endif
else
################### MinGW
#ifeq ("$(OSTYPE)", "$(OSTYPE_MINGW)")
ifneq (,$(findstring $(OSTYPE_MINGW),$(OSTYPE)))
OS_LINUX := 1
MACROS := -DOS_LINUX -DGCC -D_WIN32=1 -DTRANSFORM_MOUSE_Y=1 -DHAS_TYPEOF=1
MACROS += -DGLUT_NO_LIB_PRAGMA -DGLUT_NO_WARNING_DISABLE
INC_OPTS += -I/mingw/include/GL -I/local/include
SHARED_LIBS0 := -lm -lzlib1 -lmingw32 -lSDLmain -lSDL -lSDL_net -lpthreadGC2 -lstdc++
else
################### Linux | Cygwin
MACROS := -DGCC -DTRANSFORM_MOUSE_Y=1 -DHAS_TYPEOF=1
INC_OPTS += -I$(HOME)/include -I$(HOME)/include/GL -I/usr/include -I/usr/include/SDL -I/usr/local/include/SDL -I$(HOME)/usr/local/include/GL
# -I/home/dsk06/cscrs/c399/c399-software/include
#ifeq ("$(OSTYPE)", "$(OSTYPE_LINUX)")
ifneq (,$(findstring $(OSTYPE_LINUX),$(OSTYPE)))
################### Linux
OS_LINUX := 1
MACROS += -DOS_LINUX
#SHARED_LIBS0 += -L/usr/lib -L/usr/local/lib -L/usr/X11R6/lib -lm -lz -lSDLmain -lSDL -lSDL_net -lpthread -lGL -lGLU -lXi -lXmu -lglut -lGLEW $(MODEL_LIBS) -lstdc++
#SHARED_LIBS0 += -L$(HOME)/lib -lm -lz -lSDLmain -lSDL -lSDL_net -lpthread -lstdc++
SHARED_LIBS0 += -L$(HOME)/lib -lm -lz -lSDL -lSDL_net -lpthread -lstdc++
# -lefence
else
#ifeq ("$(OSTYPE)", "$(OSTYPE_CYGWIN)")
ifneq (,$(findstring $(OSTYPE_CYGWIN),$(OSTYPE)))
################## Cygwin
OS_CYGWIN := 1
EXE_SUFFIX:=.exe
MACROS += -DOS_CYGWIN -DSTDC_HEADERS=1 -DGLUT_IS_PRESENT=1
#-mno-cygwin
#INC_OPTS += -I/usr/include/mingw -I/usr/include/mingw/GL -I/usr/include
#$(warning "INC_OPTS=" $(INC_OPTS))
# fixme: /lib/SDL_main.o -> -lSDLmain (didn't get SDL to compile on Cygwin)
# adjust paths if necessary
SHARED_LIBS0 := -lSDL -lSDL_net -lpthread -lz -lstdc++
# GLEW not checked under cygwin!
else
# unknown OSTYPE
$(error "!!!!! unknown OSTYPE=$(OSTYPE) !!!!")
endif
endif
endif
endif
# default mode; if ORTS_MODE set, use it
# otherwise use MODE if passed, or dbg otherwise
ifeq ("$(ORTS_MODE)", "")
MODE := dbg
else
MODE := $(ORTS_MODE)
endif
OBJ_DIR := obj
CONFIG := config
SHARED_PROF_LIBS := $(SHARED_LIBS0)
SHARED_BP_LIBS := ~/lib/bmon.o $(SHARED_LIBS0)
OBJ_OPT := $(OBJ_DIR)/opt
OBJ_DBG := $(OBJ_DIR)/dbg
OBJ_SDBG := $(OBJ_DIR)/stldbg
OBJ_PROF:= $(OBJ_DIR)/prof
OBJ_BP := $(OBJ_DIR)/bp
OFLAGS := $(WARN) $(OPT) $(OPT_FRAME) # !!! -g added for 2007 competition
DFLAGS := $(WARN) -g -ggdb # -ftrapv
SDFLAGS := $(WARN) -g -ggdb -O -D_GLIBCXX_DEBUG # STL debug mode is SLOW!
PFLAGS := $(WARN) $(OPT) -pg -O
BPFLAGS := $(WARN) -g -ggdb -O2
ifeq ("$(MODE)", "opt")
FLAGS := $(OFLAGS) -DNDEBUG -Wuninitialized
#-DSCRIPT_DEBUG
STRIP := strip
OBJ := $(OBJ_OPT)
SHARED_LIBS := $(SHARED_LIBS0)
else
ifeq ("$(MODE)", "gprof")
FLAGS := $(PFLAGS) -DNDEBUG -Wuninitialized
STRIP := echo
OBJ := $(OBJ_PROF)
SHARED_LIBS := $(SHARED_PROF_LIBS)
else
ifeq ("$(MODE)", "bp")
FLAGS := $(BPFLAGS) -DNDEBUG -Wuninitialized
STRIP := echo
OBJ := $(OBJ_BP)
SHARED_LIBS := $(SHARED_BP_LIBS)
else
ifeq ("$(MODE)", "dbg")
FLAGS := $(DFLAGS)
STRIP := echo
OBJ := $(OBJ_DBG)
SHARED_LIBS := $(SHARED_LIBS0)
else
ifeq ("$(MODE)", "stldbg")
FLAGS := $(SDFLAGS)
STRIP := echo
OBJ := $(OBJ_SDBG)
SHARED_LIBS := $(SHARED_LIBS0)
else
# unknown MODE
$(error "!!!!! unknown MODE=$(MODE) !!!!")
endif
endif
endif
endif
endif
CCOPTS = $(CC_OPTS) $(MACROS) $(FLAGS) $(INC_OPTS) -DBOOST_STRICT_CONFIG
# -m32 for 32-bit applications
LD := $(CC) $(CCOPTS)
LDOPTS := $(FLAGS)
# line prefix
ifeq ("$(MDBG)", "")
VERBOSE=#
else
VERBOSE=
endif
# how to generate precompiled header file if GCC_PRECOMP=1
# otherwise, create dummy file
ALLH := All.H
ALLGCH := $(ALLH).gch
ALLGCHMODE := $(ALLGCH).$(MODE)
ifeq ("$(GCC_PRECOMP)", "1")
$(CONFIG)/$(ALLGCHMODE) : $(CONFIG)/$(ALLH)
# rm -rf $(CONFIG)/$(ALLGCH)
# echo "compile gch file"
$(VERBOSE) $(CC) $(CCOPTS) -c -o xxx1 $<
# mv xxx1 $#
# echo "link gch file"
$(VERBOSE) cd $(CONFIG); ln -sf $(ALLGCHMODE) $(ALLGCH)
else
$(CONFIG)/$(ALLGCHMODE) : $(CONFIG)/$(ALLH)
# echo "DUMMY GCH FILE"
$(VERBOSE) touch $#
endif
# link gch file to gchmode file
# depends on compiled header file
ifeq ("$(GCC_PRECOMP)", "1")
link_gch:
# echo "link gch file"
$(VERBOSE) cd $(CONFIG); ln -sf $(ALLGCHMODE) $(ALLGCH)
else
link_gch:
# echo "remove gch file"
# cd config ; rm -f $(ALLGCHMODE) $(ALLGCH)
endif
#===================================================================
# how to create dependency files
# add depfile (.d) as dependent file
# (***) (can't use $(DEP) in sed command because it contains / - so if DEP changes edit this line!
# also prepend object path for .o file
#
DEP_EXEC = $(VERBOSE) set -e; $(CC) -MM $(CCOPTS) $(INC_OPTS) $< | sed 's/$*\.o[ :]*/$(subst /,.,$(basename $<)).o dep\/$(#F) : /g' | $(AWK) '{ if (index($$1,".o") > 0) { print "$$(OBJ)/" $$0 ; } else { print $$0; } }' > $#; [ -s $# ] || rm -f $#OB
# how to compile source files
#
COMP_EXEC = $(VERBOSE) $(CC) $(CCOPTS) -c -o $# `pwd`/$<
#-------------------------------------
define create_sublib_rules2
$$(OBJ)/libs.$(subst /,.,$1).src.%.o : libs/$1/src/%.$2
# echo "comp($$(MODE)):" $$<
$$(COMP_EXEC)
$$(DEP)/libs.$(subst /,.,$1).src.%.d : libs/$1/src/%.$2
# echo dep: $$<
$$(DEP_EXEC)
endef
define create_sublib_rules
$(foreach ext,C c cpp m,$(eval $(call create_sublib_rules2,$1,$(ext))))
endef
#-------------------------------------
define create_subapp_rules2
$$(OBJ)/apps.$1.src.%.o : apps/$(subst .,/,$1)/src/%.$2
# echo "comp($$(MODE)):" $$<
$$(COMP_EXEC)
$$(DEP)/apps.$1.src.%.d : apps/$(subst .,/,$1)/src/%.$2
# echo dep: $$<
$$(DEP_EXEC)
endef
define create_subapp_rules
$(foreach ext,C c cpp,$(eval $(call create_subapp_rules2,$1,$(ext))))
endef
#===================================================================
# collect all source files, replace suffix by .o, and filter out *_main.o
# input: FILES
# output: O_FILES
define create_O_FILES
#FILES := $$(notdir $$(FILES))
C_FILES := $$(filter %.C, $$(FILES))
c_FILES := $$(filter %.c, $$(FILES))
cpp_FILES := $$(filter %.cpp, $$(FILES))
m_FILES :=
ifeq ("$(OSTYPE)","$(OSTYPE_MAC)")
#ifneq (,$(findstring $(OSTYPE_MAC),$(OSTYPE)))
m_FILES := $$(filter %.m, $$(FILES))
endif
O_FILES := $$(C_FILES:.C=.o) $$(c_FILES:.c=.o) $$(cpp_FILES:.cpp=.o) $$(m_FILES:.m=.o)
O_FILES := $$(subst /,.,$$(O_FILES))
O_FILES := $$(filter-out %_main.o, $$(O_FILES))
endef
# include all applications and dependencies (uses SHARED_LIBS for linking)
APP_SDIRS := $(subst .,/,$(APP_DIRS))
ifneq ("$(APP_DIRS)","")
#include $(patsubst %, apps/%/src/app.mk, $(APP_DIRS))
include $(patsubst %, apps/%/src/app.mk, $(APP_SDIRS))
endif
#$(warning lib_dirs="$(LIB_DIRS)")
vp := $(patsubst %, apps/%/src, $(APP_SDIRS)) \
$(patsubst %, libs/%/src, $(APP_LIBS)) \
# $(LIB_DIRS)
#vp := $(patsubst %, %/src, $(LIB_DIRS)) \
# $(patsubst %, apps/%/src, $(APP_DIRS))
INC_OPTS += -Iconfig $(addprefix -I, $(vp))
# new
INC_OPTS += $(LIB_EXT_HD) $(APP_EXT_HD)
# $(warning INC_OPTS= $(INC_OPTS))
# where source files are searched
#$(warning vp="$(vp)")
vpath %.C $(vp)
vpath %.c $(vp)
vpath %.cpp $(vp)
vpath %.m $(vp)
all_end: link_gch $(APP_DIRS)
cleanobj:
rm -f $(OBJ_OPT)/*
rm -f $(OBJ_DBG)/*
rm -f $(OBJ_SDBG)/*
rm -f $(OBJ_PROF)/*
rm -f $(OBJ_BP)/*
clean:
( rm -f bin/*; exit 0)
rm -f $(DEP)/*
rm -f $(OBJ_OPT)/*
rm -f $(OBJ_DBG)/*
rm -f $(OBJ_SDBG)/*
rm -f $(OBJ_PROF)/*
rm -f $(OBJ_BP)/*
rm -f $(CONFIG)/*.gch*
rm -rf misc/doxygen/html
find . -name "*.bprof" -exec rm -f '{}' \;
find . -name ".ui" -exec rm -f '{}'/* \;
find . -name ".moc" -exec rm -f '{}'/* \;
rmdeps:
# rm -f $(DEP)/
rpm:
cd misc/pkgs/fc7; ./makerpm; cd ../../..
# create dependency, object directories
# doesn't touch links (pointing to fast local partitions)
init:
# echo "create directories"
# config/create_dir bin
# config/create_dir $(DEP)
# config/create_dir $(OBJ_DIR)
# config/create_dir $(OBJ_OPT)
# config/create_dir $(OBJ_DBG)
# config/create_dir $(OBJ_SDBG)
# config/create_dir $(OBJ_PROF)
# config/create_dir $(OBJ_BP)
# # ln -s ../../orts_data/trunk orts_data
# (cd libs/pathfinding/dcdt; ./makelinks; exit 0) > /dev/null 2>&1
Then some changes I had to do manually, to fix errors like:
sr_bv_math.cpp:561: error: ‘isnan’ was not declared in this scope
Edit the file trunk/libs/pathfinding/dcdt/sr/src/sr_bv_math.cpp and right after the cmath include, declare isnan as extern:
#include <cmath>
extern "C" int isnan(double);
That compiled the binaries, but then I had to also download orts_data.tgz to run the applications.
Well, running ortsg for the very first time failed, reporting:
texture size = 64X64
REMARK: can't open file: testgame/ortsg/terrain.tga
REMARK: can't open file: testgame/ortsg/noise.tga
Unable to load terrain noise texture testgame/ortsg/noise.tga
ERROR: /Users/karlphillip/installers/orts/orts/trunk/libs/gfxclient/src/GfxTerrain.C GfxTerrain() (line 213): failed to load noise image testgame/ortsg/noise.tga
REMARK: closing connection
REMARK: !!! already closed
REMARK: ~IO_Buffer called
Even though the files are there. So I KILLED the application and tried it again:
2011-11-27 01:51:02.947 ortsg[390:903] GLUT Warning: glutInit being called a second time.
seed=1322365862
ERROR: /Users/karlphillip/installers/orts/orts/trunk/libs/network/src/TCP_Client.C connect() (line 27): can't connect
REMARK: mixer not open
REMARK: closing connection
REMARK: !!! already closed
/Users/karlphillip/installers/orts/orts/trunk/libs/network/src/TCP_Client.C connect() (line 27): can't connect
Abort trap
The first line of the error might be familiar to you. Even though the app was killed, something seems to be left hanging somewhere, and the only way I found to bypass the error and have a clean run of the application was rebooting my computer.
It seems this application has issues on Mac OS X and need immediate fixing. I suggest you install a Linux VM, or even a Windows VM inside your Mac to be able to run orts, if you really have to use it.