mirror of
https://github.com/nasa/trick.git
synced 2025-04-07 19:34:23 +00:00
Autogenerate dependencies in trickify.mk
By using gcc's dependency generation feature, we can execute ICG only when necessary, instead of all the time. Refs #309
This commit is contained in:
parent
9d587a45c2
commit
90a26ab7c7
@ -1,35 +1,37 @@
|
||||
# This file can be used to create a library containing the io_* and py_* code that Trick would
|
||||
# normally generate during the simulation build process. Sims can then link against this library,
|
||||
# reducing compilation time.
|
||||
# This file can be used to create a library containing the io_* and py_* code
|
||||
# that Trick would normally generate during the simulation build process. Sims
|
||||
# can then link against this library, reducing compilation time.
|
||||
#
|
||||
# To use it, create a directory that includes a file named S_source.hh that includes all header
|
||||
# files for which you want io_* and py_* code generated. This is not the S_source.hh that Trick
|
||||
# generates during compilation, but Trick's tools assume this name for now, so you have to use it.
|
||||
# Then, in that directory, run the following command:
|
||||
# To use it, create a directory that includes a file named S_source.hh that
|
||||
# includes all header files for which you want io_* and py_* code generated.
|
||||
# This is not the S_source.hh that Trick generates during compilation, but
|
||||
# Trick's tools assume this name for now, so you have to use it. Then, in that
|
||||
# directory, run the following command:
|
||||
#
|
||||
# make -f $(TRICK_HOME)/share/trick/makefiles/trickify.mk
|
||||
#
|
||||
# You can, of course, call this from your own makefile. But remember to switch to the directory
|
||||
# containing your S_source.hh first using make's -C option if necessary. For instance:
|
||||
# You can, of course, call this from your own makefile. But remember to switch
|
||||
# to the directory containing your S_source.hh first using make's -C option if
|
||||
# necessary. For instance:
|
||||
#
|
||||
# all:
|
||||
# $(MAKE) -C <directory> -f $(TRICK_HOME)/share/trick/makefiles/trickify.mk
|
||||
#
|
||||
# There are a number of variables you can export from your own makefile or define on the
|
||||
# command line when calling make:
|
||||
# There are a number of variables you can export from your own makefile or
|
||||
# define on the command line when calling make:
|
||||
#
|
||||
# TRICKIFY_CXX_FLAGS (required)
|
||||
# Define this variable to specify compiler flags. Most importantly, include the paths to the header
|
||||
# files included by your S_source.hh.
|
||||
# For instance: -I$(HOME)/myproject/foo/include -I$(HOME)/myproject/bar/include
|
||||
# Define this variable to specify compiler flags. Most importantly, include the
|
||||
# paths to the header files included by your S_source.hh. For instance:
|
||||
# -I$(HOME)/myproject/foo/include -I$(HOME)/myproject/bar/include
|
||||
#
|
||||
# TRICKIFY_LIB_NAME (optional)
|
||||
# The name of the generated library file. The default value is libtrickified.a. You should
|
||||
# choose something more meaningful, like libmyproject_trick.a.
|
||||
# The name of the generated library file. The default value is libtrickified.a.
|
||||
# You should choose something more meaningful, like libmyproject_trick.a.
|
||||
#
|
||||
# TRICKIFY_PTYON_DIR (optional)
|
||||
# The directory into which generated Python modules are placed. The default value is python (in
|
||||
# the current directory).
|
||||
# The directory into which generated Python modules are placed. The default
|
||||
# value is python (in the current directory).
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
@ -66,7 +68,8 @@
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# See github.com/nasa/trick/wiki/Trickified-Project-Libraries for more information.
|
||||
# For more information, see:
|
||||
# github.com/nasa/trick/wiki/Trickified-Project-Libraries
|
||||
|
||||
ifndef TRICKIFY_CXX_FLAGS
|
||||
$(error TRICKIFY_CXX_FLAGS must be set)
|
||||
@ -90,7 +93,8 @@ TRICK_CXXFLAGS += $(TRICKIFY_CXX_FLAGS)
|
||||
# Ensure we can process all headers
|
||||
TRICK_EXT_LIB_DIRS :=
|
||||
|
||||
# While it would be nice to invoke the implicit archiving rule via a target like:
|
||||
# While it would be nice to invoke the implicit archiving rule via a target
|
||||
# like:
|
||||
#
|
||||
# $(TRICKIFY_LIB_NAME): $(TRICKIFY_LIB_NAME)($(OBJECTS))
|
||||
#
|
||||
@ -101,60 +105,6 @@ $(TRICKIFY_LIB_NAME): $(OBJECTS) | $(dir $(TRICKIFY_LIB_NAME))
|
||||
$(info $(call COLOR,Linking) $@)
|
||||
@ar rsc $@ $?
|
||||
|
||||
# $(OBJECTS) is meant to contain all of the py_* and io_* object file names. We can't construct
|
||||
# those until we run ICG and convert_swig. But we can't run the rules for ICG and convert_swig
|
||||
# before $(OBJECTS) is expanded because it is a prerequiste of $(TRICKIFY_LIB_NAME), and prerequisites are always
|
||||
# immediately expanded. Therefore, when make processes this file (for the first time after a clean),
|
||||
# $(OBJECTS) is empty, because the find will be executed before ICG and convert_swig have created
|
||||
# any files. What we really want is to run ICG and convert_swig before $(OBJECTS) is expanded.
|
||||
#
|
||||
# We can do this by taking advantage of (abusing) make's behavior in the presence of included
|
||||
# makefiles. When you include another makefile, make attempts to update that file, and then
|
||||
# reexecutes the original makefile with a clean slate if any of the included makefiles changed. So
|
||||
# we need a rule that will always run ICG and convert_swig to check for header changes and update
|
||||
# some file only when changes have occurred. We can then include that "marker" file to trigger make
|
||||
# to reexecute this main makefile, thus updating $(OBJECTS) to the latest results of ICG and
|
||||
# convert_swig.
|
||||
#
|
||||
# The file that fits our purpose is build/Makefile_ICG, which is only updated when convert_swig
|
||||
# detects header changes. By including and making a rule for that file, we can run ICG and
|
||||
# convert_swig, reexecute this makefile if necessary, and update $(OBJECTS) before running the rule
|
||||
# for $(TRICKIFY_LIB_NAME). To force this rule to always execute, we add a prerequisite on a non-existent file, a
|
||||
# role the icg rule can conveniently fill. Note that the normal methods of using :: or .PHONY do not
|
||||
# work on rules for making makefiles, as they would cause infinite reexecution.
|
||||
#
|
||||
# Ultimately, it looks like this:
|
||||
# 1. make starts
|
||||
# 2. make includes build/Makefile_ICG
|
||||
# 3. make looks for a rule to update build/Makefile_ICG
|
||||
# 4. the build/Makefile_ICG rule depends on icg
|
||||
# 5. icg doesn't exist, so the icg rule is run, which executes ICG
|
||||
# 6. the build/Makefile_ICG rule is run, which executes convert_swig
|
||||
# 7. if convert_swig detects header changes, it updates the build/Makefile_ICG file
|
||||
# 8. if the build/Makefile_ICG file changed, make reexecutes the top makefile (this file)
|
||||
# 9. repeat steps 1 through 6
|
||||
# 10. although ICG and convert_swig are run again, there have been no header changes, so
|
||||
# build/Makefile_ICG is not updated
|
||||
# 11. since no included makefiles have changed, make continues processing the top makefile (this
|
||||
# file)
|
||||
# 12. $(OBJECTS) now contains an updated list of files
|
||||
# 13. $(TRICKIFY_LIB_NAME) can be executed with the correct prerequisites
|
||||
#
|
||||
# Note that build/Makefile_ICG is included after our main target since it contains targets itself,
|
||||
# and we want make without an argument to build $(TRICKIFY_LIB_NAME).
|
||||
#
|
||||
# Note also that this executes ICG and convert_swig every time this file is processed, regardless
|
||||
# of the target. Wasteful, but acceptable.
|
||||
|
||||
-include build/Makefile_ICG
|
||||
|
||||
build/Makefile_ICG: icg
|
||||
@$(TRICK_HOME)/libexec/trick/make_makefile_swig
|
||||
@$(TRICK_HOME)/libexec/trick/convert_swig
|
||||
|
||||
icg:
|
||||
@$(TRICK_HOME)/bin/trick-ICG $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) $(TRICK_ICGFLAGS) S_source.hh
|
||||
|
||||
$(dir $(TRICKIFY_LIB_NAME)) $(TRICKIFY_PYTHON_DIR):
|
||||
@mkdir -p $@
|
||||
|
||||
@ -165,3 +115,41 @@ $(dir $(TRICKIFY_LIB_NAME)) $(TRICKIFY_PYTHON_DIR):
|
||||
%.o: %.cpp
|
||||
$(info $(call COLOR,Compiling) $<)
|
||||
@$(TRICK_CC) $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) $(PYTHON_INCLUDES) -std=c++11 -Wno-invalid-offsetof -Wno-shadow -c -o $@ $<
|
||||
|
||||
# $(OBJECTS) is meant to contain all of the py_* and io_* object file names. We
|
||||
# can't construct those until we run ICG and convert_swig. But we can't run the
|
||||
# rule for ICG and convert_swig before $(OBJECTS) is expanded because it is a
|
||||
# prerequiste of $(TRICKIFY_LIB_NAME), and prerequisites are always immediately
|
||||
# expanded. Therefore, when make processes this file (for the first time after
|
||||
# a clean), $(OBJECTS) is empty, because the find will be executed before ICG
|
||||
# and convert_swig have created any files. What we really want is to run ICG
|
||||
# and convert_swig before $(OBJECTS) is expanded.
|
||||
#
|
||||
# We can do this by taking advantage of (abusing) make's behavior in the
|
||||
# presence of included files. When you include another file, make attempts to
|
||||
# update that file, and then reexecutes the original makefile with a clean
|
||||
# slate if any of the included files changed. So we need a rule that:
|
||||
#
|
||||
# 1. Executes only if S_source.hh or anything in its include tree changes.
|
||||
# 2. Runs ICG and convert_swig to generate py_* and io_* files.
|
||||
# 3. Updates its dependency file.
|
||||
#
|
||||
# We can then include the dependency file to trigger make to reexecute this
|
||||
# main makefile if changes were detected, thus updating $(OBJECTS) to the
|
||||
# latest results of ICG and convert_swig.
|
||||
#
|
||||
# gcc's option to automatically generate dependency information is exactly
|
||||
# what we need. It will produce a file containing a make rule whose
|
||||
# dependencies are everyting in S_source.hh's include tree plus S_source.hh
|
||||
# itself. By telling gcc to make the target of the rule the same target we use
|
||||
# to execute the gcc call, we end up with a target that maintains its own
|
||||
# dependency list. The method is laid out in more detail here:
|
||||
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
|
||||
|
||||
build/S_source.d:
|
||||
@$(TRICK_HOME)/bin/trick-ICG $(TRICK_CXXFLAGS) $(TRICK_SYSTEM_CXXFLAGS) $(TRICK_ICGFLAGS) S_source.hh
|
||||
@$(TRICK_HOME)/libexec/trick/make_makefile_swig
|
||||
@$(TRICK_HOME)/libexec/trick/convert_swig
|
||||
@$(TRICK_CC) -MM -MP -MT $@ -MF $@ $(TRICKIFY_CXX_FLAGS) S_source.hh
|
||||
|
||||
-include build/S_source.d
|
||||
|
Loading…
x
Reference in New Issue
Block a user