Rebuild sources if configuration is changed

This commit adds a check for configuration data changes. If a change in
configuration data is detected, all the sources in the tree are rebuilt.

This is a fix for #2073. #2162 was originally proposed as a fix, but it
was agreed that `--preinclude` is a more convenient way to include
configuration data, since it can be used to change the behaviour of
source files that don't include "mbed_config.h" directly, which is a big
advantage when importing 3rd party source trees. Compared to #2162, this
commit has the disadvantage of rebuilding all the source files if a
configuration change is detected, but it was agreed that the advantage
of using `--preinclude` outweighs the disadvantage of the increased
compilation time.
pull/2177/head
Bogdan Marinescu 2016-07-15 16:37:46 +03:00
parent ee2f9174ad
commit a558c49240
1 changed files with 56 additions and 13 deletions

View File

@ -17,7 +17,7 @@ limitations under the License.
import re import re
import sys import sys
from os import stat, walk, getcwd, sep from os import stat, walk, getcwd, sep, remove
from copy import copy from copy import copy
from time import time, sleep from time import time, sleep
from types import ListType from types import ListType
@ -252,6 +252,12 @@ class mbedToolchain:
# This will hold the configuration data (as returned by Config.get_config_data()) # This will hold the configuration data (as returned by Config.get_config_data())
self.config_data = None self.config_data = None
# This will hold the location of the configuration file or None if there's no configuration available
self.config_file = None
# Call guard for "get_config_data" (see the comments of get_config_data for details)
self.config_processed = False
# Non-incremental compile # Non-incremental compile
self.build_all = False self.build_all = False
@ -663,6 +669,9 @@ class mbedToolchain:
queue = [] queue = []
prev_dir = None prev_dir = None
# Generate configuration header (this will update self.build_all if needed)
self.get_config_header()
# Sort compile queue for consistency # Sort compile queue for consistency
files_to_compile.sort() files_to_compile.sort()
work_dir = getcwd() work_dir = getcwd()
@ -944,19 +953,53 @@ class mbedToolchain:
def set_config_data(self, config_data): def set_config_data(self, config_data):
self.config_data = config_data self.config_data = config_data
# Return the location of the config header. This function will create the config # Creates the configuration header if needed:
# header first if needed. The header will be written in a file called "mbed_conf.h" # - if there is no configuration data, "mbed_config.h" is not create (or deleted if it exists).
# located in the project's build directory. # - if there is configuration data and "mbed_config.h" does not exist, it is created.
# If config headers are not used (self.config_header_content is None), the function # - if there is configuration data similar to the previous configuration data,
# returns None # "mbed_config.h" is left untouched.
# - if there is new configuration data, "mbed_config.h" is overriden.
# The function needs to be called exactly once for the lifetime of this toolchain instance.
# The "config_processed" variable (below) ensures this behaviour.
# The function returns the location of the configuration file, or None if there is no
# configuration data available (and thus no configuration file)
def get_config_header(self): def get_config_header(self):
if self.config_data is None: if self.config_processed: # this function was already called, return its result
return None return self.config_file
config_file = join(self.build_dir, self.MBED_CONFIG_FILE_NAME) # The config file is located in the build directory
if not exists(config_file): self.config_file = join(self.build_dir, self.MBED_CONFIG_FILE_NAME)
with open(config_file, "wt") as f: # If the file exists, read its current content in prev_data
f.write(Config.config_to_header(self.config_data)) if exists(self.config_file):
return config_file with open(self.config_file, "rt") as f:
prev_data = f.read()
else:
prev_data = None
# Get the current configuration data
crt_data = Config.config_to_header(self.config_data) if self.config_data else None
# "changed" indicates if a configuration change was detected
changed = False
if prev_data is not None: # a previous mbed_config.h exists
if crt_data is None: # no configuration data, so "mbed_config.h" needs to be removed
remove(self.config_file)
self.config_file = None # this means "config file not present"
changed = True
elif crt_data != prev_data: # different content of config file
with open(self.config_file, "wt") as f:
f.write(crt_data)
changed = True
else: # a previous mbed_config.h does not exist
if crt_data is not None: # there's configuration data available
with open(self.config_file, "wt") as f:
f.write(crt_data)
changed = True
else:
self.config_file = None # this means "config file not present"
# If there was a change in configuration, rebuild everything
self.build_all = changed
# Make sure that this function will only return the location of the configuration
# file for subsequent calls, without trying to manipulate its content in any way.
self.config_processed = True
return self.config_file
# Return the list of macros geenrated by the build system # Return the list of macros geenrated by the build system
def get_config_macros(self): def get_config_macros(self):