diff --git a/.gitignore b/.gitignore index 9f5386bd0..dd5959f69 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -build/inc/ +build +Makefile diff --git a/Makefile.sample b/Makefile.sample new file mode 100644 index 000000000..a49cd2093 --- /dev/null +++ b/Makefile.sample @@ -0,0 +1,152 @@ +# +# Operating System Abstraction Layer CMake / GNU make wrapper +# +# ABOUT THIS MAKEFILE: +# It is a GNU-make wrapper that calls the CMake tools appropriately +# so that setting up a new build is fast and easy with no need to +# learn the CMake commands. It also makes it easier to integrate +# the build with IDE tools such as Eclipse by providing a default +# makefile that has the common targets such as all/clean/etc. +# +# Use of this file is optional. +# +# For _ALL_ targets defined in this file the build tree location may +# be specified via the "O" variable (i.e. make O= all). +# If not specified then the "build" subdirectory will be assumed. +# +# This wrapper defines the following major targets: +# prep -- Runs CMake to create a new or re-configure an existing build tree +# Note that multiple build trees can exist from a single source +# Other control options may be passed to CMake via +# make variables depending on the mission build scripts. These will be +# cached in the build tree so they do not need to be set again thereafter. +# +# all -- Build all targets in the CMake build tree +# +# install -- Copy all files to the installation tree and run packaging scripts +# The "DESTDIR" and "INSTALLPREFIX" environment variables control where the +# files are copied +# +# clean -- Clean all targets in the CMake build tree, but not the build tree itself. +# +# distclean -- Entirely remove the build directory specified by "O" +# Note that after this the "prep" step must be run again in order to build. +# Use caution with this as it does an rm -rf - don't set O to your home dir! +# +# test -- Run all unit tests defined in the build on the host. This will not +# work if the BSPTYPE selection is not compatible with the host. +# In that case it is up to the user to copy the executables to the target +# and run them. +# +# lcov -- Runs the "lcov" tool on the build tree to collect all code coverage +# analysis data and build the reports. Code coverage data may be created by +# the "make test" target above. +# + +# Establish default values for critical variables. Any of these may be overridden +# on the command line or via the make environment configuration in an IDE +O ?= build +BSPTYPE ?= generic-linux +BUILDTYPE ?= debug +INSTALLPREFIX ?= /exe +DESTDIR ?= $(O) + +# The "DESTDIR" variable is a bit more complicated because it should be an absolute +# path for CMake, but we want to accept either absolute or relative paths. So if +# the path does NOT start with "/", prepend it with the current directory. +ifeq ($(filter /%, $(DESTDIR)),) +DESTDIR := $(CURDIR)/$(DESTDIR) +endif + +# The "LOCALTGTS" defines the top-level targets that are implemented in this makefile +# Any other target may also be given, in that case it will simply be passed through. +LOCALTGTS := prep all clean install distclean test lcov +OTHERTGTS := $(filter-out $(LOCALTGTS),$(MAKECMDGOALS)) + +# As this makefile does not build any real files, treat everything as a PHONY target +# This ensures that the rule gets executed even if a file by that name does exist +.PHONY: $(LOCALTGTS) $(OTHERTGTS) + +# If the target name appears to be a directory (ends in /), do a make all in that directory +DIRTGTS := $(filter %/,$(OTHERTGTS)) +ifneq ($(DIRTGTS),) +$(DIRTGTS): + $(MAKE) -C $(O)/$(patsubst $(O)/%,%,$(@)) all +endif + +# For any other goal that is not one of the known local targets, pass it to the build +# as there might be a target by that name. For example, this is useful for rebuilding +# single unit test executable files while debugging from the IDE +FILETGTS := $(filter-out $(DIRTGTS),$(OTHERTGTS)) +ifneq ($(FILETGTS),) +$(FILETGTS): + $(MAKE) -C $(O) $(@) +endif + +# The "prep" step requires extra options that are specified via enviroment variables. +# Certain special ones should be passed via cache (-D) options to CMake. +# These are only needed for the "prep" target but they are computed globally anyway. +# +# Note this simple makefile just builds for one target, could trivally manage +# multiple targets by changing build directory. More complex target +# list examples are provide by cFE.. +PREP_OPTS := -DOSAL_SYSTEM_BSPTYPE=$(BSPTYPE) -DINSTALL_TARGET_LIST=. + +ifneq ($(INSTALLPREFIX),) +PREP_OPTS += -DCMAKE_INSTALL_PREFIX=$(INSTALLPREFIX) +endif + +ifneq ($(VERBOSE),) +PREP_OPTS += --trace +endif + +ifneq ($(OMIT_DEPRECATED),) +PREP_OPTS += -DOSAL_OMIT_DEPRECATED=$(OMIT_DEPRECATED) +endif + +ifneq ($(BUILDTYPE),) +PREP_OPTS += -DCMAKE_BUILD_TYPE=$(BUILDTYPE) +endif + +ifneq ($(ENABLE_UNIT_TESTS),) +PREP_OPTS += -DENABLE_UNIT_TESTS=$(ENABLE_UNIT_TESTS) +endif + +ifneq ($(PERMISSIVE_MODE),) +PREP_OPTS += -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=$(PERMISSIVE_MODE) +endif + +all: + $(MAKE) --no-print-directory -C "$(O)" all + +install: + $(MAKE) --no-print-directory -C "$(O)" DESTDIR="${DESTDIR}" install + +prep $(O)/.prep: + mkdir -p "$(O)" + (cd "$(O)" && cmake $(PREP_OPTS) "$(CURDIR)") + echo "$(PREP_OPTS)" > "$(O)/.prep" + +clean: + $(MAKE) --no-print-directory -C "$(O)" clean + +distclean: + rm -rf "$(O)" + +# Grab lcov baseline before running tests +test: + lcov --capture --initial --directory $(O) --output-file $(O)/coverage_base.info + $(MAKE) --no-print-directory -C "$(O)" test + +lcov: + lcov --capture --rc lcov_branch_coverage=1 --directory $(O) --output-file $(O)/coverage_test.info + lcov --rc lcov_branch_coverage=1 --add-tracefile $(O)/coverage_base.info --add-tracefile $(O)/coverage_test.info --output-file $(O)/coverage_total.info + genhtml $(O)/coverage_total.info --branch-coverage --output-directory $(O)/lcov + @/bin/echo -e "\n\nCoverage Report Link: file:$(CURDIR)/$(O)/lcov/index.html\n" + + +# Make all the commands that use the build tree depend on a flag file +# that is used to indicate the prep step has been done. This way +# the prep step does not need to be done explicitly by the user +# as long as the default options are sufficient. +$(filter-out prep distclean,$(LOCALTGTS)): $(O)/.prep