ldgen: pass component libraries directly
This commit is contained in:
parent
ca6cff7637
commit
b1ecd75d83
5 changed files with 66 additions and 76 deletions
|
@ -1,7 +1,6 @@
|
||||||
# Makefile to support the linker script generation mechanism
|
# Makefile to support the linker script generation mechanism
|
||||||
|
|
||||||
LDGEN_SECTIONS_INFO_FILES = $(foreach lib, $(COMPONENT_LIBRARIES), $(BUILD_DIR_BASE)/$(lib)/lib$(lib).a.sections_info)
|
|
||||||
LDGEN_FRAGMENT_FILES = $(COMPONENT_LDFRAGMENTS)
|
LDGEN_FRAGMENT_FILES = $(COMPONENT_LDFRAGMENTS)
|
||||||
|
LDGEN_LIBRARIES=$(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a)
|
||||||
|
|
||||||
ON_WINDOWS:=n
|
ON_WINDOWS:=n
|
||||||
|
|
||||||
|
@ -15,54 +14,45 @@ endif
|
||||||
# the components
|
# the components
|
||||||
ifeq ($(ON_WINDOWS),y)
|
ifeq ($(ON_WINDOWS),y)
|
||||||
define ldgen_process_template
|
define ldgen_process_template
|
||||||
$(BUILD_DIR_BASE)/ldgen.section_infos: $(LDGEN_SECTIONS_INFO_FILES) $(IDF_PATH)/make/ldgen.mk
|
$(BUILD_DIR_BASE)/ldgen.section_infos: $(LDGEN_LIBRARIES) $(IDF_PATH)/make/ldgen.mk
|
||||||
printf "$(foreach info,$(LDGEN_SECTIONS_INFO_FILES),$(subst \,/,$(shell cygpath -w $(info)))\n)" > $(BUILD_DIR_BASE)/ldgen.section_infos
|
printf "$(foreach info,$(LDGEN_LIBRARIES),$(subst \,/,$(shell cygpath -w $(info)))\n)" > $(BUILD_DIR_BASE)/ldgen_libraries
|
||||||
|
|
||||||
$(2): $(1) $(LDGEN_FRAGMENT_FILES) $(SDKCONFIG) $(BUILD_DIR_BASE)/ldgen.section_infos
|
$(2): $(1) $(LDGEN_FRAGMENT_FILES) $(SDKCONFIG) $(BUILD_DIR_BASE)/ldgen_libraries
|
||||||
@echo 'Generating $(notdir $(2))'
|
@echo 'Generating $(notdir $(2))'
|
||||||
$(PYTHON) $(IDF_PATH)/tools/ldgen/ldgen.py \
|
$(PYTHON) $(IDF_PATH)/tools/ldgen/ldgen.py \
|
||||||
--input $(1) \
|
--input $(1) \
|
||||||
--config $(SDKCONFIG) \
|
--config $(SDKCONFIG) \
|
||||||
--fragments $(LDGEN_FRAGMENT_FILES) \
|
--fragments $(LDGEN_FRAGMENT_FILES) \
|
||||||
|
--libraries-file $(BUILD_DIR_BASE)/ldgen_libraries \
|
||||||
--output $(2) \
|
--output $(2) \
|
||||||
--sections $(BUILD_DIR_BASE)/ldgen.section_infos \
|
|
||||||
--kconfig $(IDF_PATH)/Kconfig \
|
--kconfig $(IDF_PATH)/Kconfig \
|
||||||
--env "COMPONENT_KCONFIGS=$(foreach k, $(COMPONENT_KCONFIGS), $(shell cygpath -w $(k)))" \
|
--env "COMPONENT_KCONFIGS=$(foreach k, $(COMPONENT_KCONFIGS), $(shell cygpath -w $(k)))" \
|
||||||
--env "COMPONENT_KCONFIGS_PROJBUILD=$(foreach k, $(COMPONENT_KCONFIGS_PROJBUILD), $(shell cygpath -w $(k)))" \
|
--env "COMPONENT_KCONFIGS_PROJBUILD=$(foreach k, $(COMPONENT_KCONFIGS_PROJBUILD), $(shell cygpath -w $(k)))" \
|
||||||
--env "IDF_CMAKE=n"
|
--env "IDF_CMAKE=n" \
|
||||||
|
--objdump $(OBJDUMP)
|
||||||
endef
|
endef
|
||||||
else # ON_WINDOWS
|
else # ON_WINDOWS
|
||||||
define ldgen_process_template
|
define ldgen_process_template
|
||||||
$(BUILD_DIR_BASE)/ldgen.section_infos: $(LDGEN_SECTIONS_INFO_FILES) $(IDF_PATH)/make/ldgen.mk
|
$(BUILD_DIR_BASE)/ldgen_libraries: $(LDGEN_LIBRARIES) $(IDF_PATH)/make/ldgen.mk
|
||||||
printf "$(foreach info,$(LDGEN_SECTIONS_INFO_FILES),$(info)\n)" > $(BUILD_DIR_BASE)/ldgen.section_infos
|
printf "$(foreach library,$(LDGEN_LIBRARIES),$(library)\n)" > $(BUILD_DIR_BASE)/ldgen_libraries
|
||||||
|
|
||||||
$(2): $(1) $(LDGEN_FRAGMENT_FILES) $(SDKCONFIG) $(BUILD_DIR_BASE)/ldgen.section_infos
|
$(2): $(1) $(LDGEN_FRAGMENT_FILES) $(SDKCONFIG) $(BUILD_DIR_BASE)/ldgen_libraries
|
||||||
@echo 'Generating $(notdir $(2))'
|
@echo 'Generating $(notdir $(2))'
|
||||||
$(PYTHON) $(IDF_PATH)/tools/ldgen/ldgen.py \
|
$(PYTHON) $(IDF_PATH)/tools/ldgen/ldgen.py \
|
||||||
--input $(1) \
|
--input $(1) \
|
||||||
--config $(SDKCONFIG) \
|
--config $(SDKCONFIG) \
|
||||||
--fragments $(LDGEN_FRAGMENT_FILES) \
|
--fragments $(LDGEN_FRAGMENT_FILES) \
|
||||||
|
--libraries-file $(BUILD_DIR_BASE)/ldgen_libraries \
|
||||||
--output $(2) \
|
--output $(2) \
|
||||||
--sections $(BUILD_DIR_BASE)/ldgen.section_infos \
|
|
||||||
--kconfig $(IDF_PATH)/Kconfig \
|
--kconfig $(IDF_PATH)/Kconfig \
|
||||||
--env "COMPONENT_KCONFIGS=$(COMPONENT_KCONFIGS)" \
|
--env "COMPONENT_KCONFIGS=$(COMPONENT_KCONFIGS)" \
|
||||||
--env "COMPONENT_KCONFIGS_PROJBUILD=$(COMPONENT_KCONFIGS_PROJBUILD)" \
|
--env "COMPONENT_KCONFIGS_PROJBUILD=$(COMPONENT_KCONFIGS_PROJBUILD)" \
|
||||||
--env "IDF_CMAKE=n"
|
--env "IDF_CMAKE=n" \
|
||||||
|
--objdump $(OBJDUMP)
|
||||||
endef
|
endef
|
||||||
endif # ON_WINDOWS
|
endif # ON_WINDOWS
|
||||||
|
|
||||||
define ldgen_create_commands
|
define ldgen_create_commands
|
||||||
$(foreach lib, $(COMPONENT_LIBRARIES), \
|
|
||||||
$(eval $(call ldgen_generate_target_sections_info, $(BUILD_DIR_BASE)/$(lib)/lib$(lib).a)))
|
|
||||||
|
|
||||||
ldgen-clean:
|
ldgen-clean:
|
||||||
rm -f $(LDGEN_SECTIONS_INFO_FILES)
|
rm -f $(BUILD_DIR_BASE)/ldgen_libraries
|
||||||
rm -f $(BUILD_DIR_BASE)/ldgen.section_infos
|
|
||||||
endef
|
|
||||||
|
|
||||||
# Target to generate sections info file from objdump of component archive
|
|
||||||
define ldgen_generate_target_sections_info
|
|
||||||
$(1).sections_info: $(1)
|
|
||||||
@echo 'Generating $(notdir $(1).sections_info)'
|
|
||||||
$(OBJDUMP) -h $(1) > $(1).sections_info
|
|
||||||
endef
|
endef
|
|
@ -64,7 +64,7 @@ function(register_component)
|
||||||
|
|
||||||
set_property(TARGET ${COMPONENT_TARGET} PROPERTY OUTPUT_NAME ${COMPONENT_NAME})
|
set_property(TARGET ${COMPONENT_TARGET} PROPERTY OUTPUT_NAME ${COMPONENT_NAME})
|
||||||
|
|
||||||
ldgen_generate_sections_info(${COMPONENT_TARGET})
|
ldgen_component_add(${COMPONENT_TARGET})
|
||||||
else()
|
else()
|
||||||
add_library(${COMPONENT_TARGET} INTERFACE) # header-only component
|
add_library(${COMPONENT_TARGET} INTERFACE) # header-only component
|
||||||
set(include_type INTERFACE)
|
set(include_type INTERFACE)
|
||||||
|
|
|
@ -1,45 +1,34 @@
|
||||||
# Utilities for supporting linker script generation in the build system
|
# Utilities for supporting linker script generation in the build system
|
||||||
|
|
||||||
# ldgen_create_target
|
# ldgen_set_variables
|
||||||
#
|
#
|
||||||
# Create the custom target to attach the fragment files and template files
|
# Create the custom target to attach the fragment files and template files
|
||||||
# for the build to.
|
# for the build to.
|
||||||
function(ldgen_set_variables)
|
function(ldgen_set_variables)
|
||||||
add_custom_target(ldgen_section_infos)
|
add_custom_target(ldgen)
|
||||||
add_custom_target(ldgen DEPENDS ldgen_section_infos)
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# ldgen_add_fragment_file
|
# ldgen_add_fragment_files
|
||||||
#
|
#
|
||||||
# Add one or more linker fragment files, and append it to the list of fragment
|
# Add one or more linker fragment files, and append it to the list of fragment
|
||||||
# files found so far.
|
# files found so far.
|
||||||
function(ldgen_add_fragment_files target fragment_files)
|
function(ldgen_add_fragment_files component fragment_files)
|
||||||
spaces2list(fragment_files)
|
spaces2list(fragment_files)
|
||||||
|
|
||||||
foreach(fragment_file ${fragment_files})
|
foreach(fragment_file ${fragment_files})
|
||||||
get_filename_component(fragment_file_abs_dir ${fragment_file} ABSOLUTE BASE_DIR ${component_dir})
|
get_filename_component(_fragment_file ${fragment_file} ABSOLUTE)
|
||||||
list(APPEND fragment_files_full_path ${fragment_file_abs_dir})
|
list(APPEND _fragment_files ${_fragment_file})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
set_property(TARGET ldgen APPEND PROPERTY FRAGMENT_FILES ${fragment_files_full_path})
|
set_property(TARGET ldgen APPEND PROPERTY FRAGMENT_FILES ${_fragment_files})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# ldgen_generate_sections_info
|
# ldgen_component_add
|
||||||
#
|
#
|
||||||
# Generate sections info for specified target to be used in linker script generation
|
# Add component to known libraries for linker script generation
|
||||||
function(ldgen_generate_sections_info target)
|
function(ldgen_component_add component_lib)
|
||||||
get_filename_component(target_sections_info ${CMAKE_CURRENT_BINARY_DIR}/${target}.sections_info ABSOLUTE)
|
set_property(TARGET ldgen APPEND PROPERTY OUTPUT_LIBRARIES "$<TARGET_FILE:${component_lib}>")
|
||||||
|
set_property(TARGET ldgen APPEND PROPERTY LIBRARIES ${component_lib})
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${target_sections_info}
|
|
||||||
COMMAND ${CMAKE_OBJDUMP} $<TARGET_FILE:${target}> -h > ${target_sections_info}
|
|
||||||
DEPENDS ${target}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_target(${target}_sections_info DEPENDS ${target_sections_info})
|
|
||||||
add_dependencies(ldgen_section_infos ${target}_sections_info)
|
|
||||||
|
|
||||||
set_property(TARGET ldgen_section_infos APPEND PROPERTY SECTIONS_INFO_FILES ${target_sections_info})
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# ldgen_process_template
|
# ldgen_process_template
|
||||||
|
@ -47,10 +36,17 @@ endfunction()
|
||||||
# Passes a linker script template to the linker script generation tool for
|
# Passes a linker script template to the linker script generation tool for
|
||||||
# processing
|
# processing
|
||||||
function(ldgen_process_template template output)
|
function(ldgen_process_template template output)
|
||||||
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/ldgen.section_infos
|
get_property(output_libraries TARGET ldgen PROPERTY OUTPUT_LIBRARIES)
|
||||||
CONTENT "$<JOIN:$<TARGET_PROPERTY:ldgen_section_infos,SECTIONS_INFO_FILES>,\n>")
|
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/ldgen_libraries.in CONTENT "$<JOIN:${output_libraries},\n>")
|
||||||
|
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/ldgen_libraries INPUT ${CMAKE_BINARY_DIR}/ldgen_libraries.in)
|
||||||
|
|
||||||
|
get_filename_component(filename "${template}" NAME_WE)
|
||||||
|
|
||||||
|
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
|
||||||
|
"${CMAKE_BINARY_DIR}/ldgen_libraries.in"
|
||||||
|
"${CMAKE_BINARY_DIR}/ldgen_libraries")
|
||||||
|
|
||||||
# Create command to invoke the linker script generator tool.
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${output}
|
OUTPUT ${output}
|
||||||
COMMAND ${PYTHON} ${IDF_PATH}/tools/ldgen/ldgen.py
|
COMMAND ${PYTHON} ${IDF_PATH}/tools/ldgen/ldgen.py
|
||||||
|
@ -58,15 +54,16 @@ function(ldgen_process_template template output)
|
||||||
--fragments "$<JOIN:$<TARGET_PROPERTY:ldgen,FRAGMENT_FILES>,\t>"
|
--fragments "$<JOIN:$<TARGET_PROPERTY:ldgen,FRAGMENT_FILES>,\t>"
|
||||||
--input ${template}
|
--input ${template}
|
||||||
--output ${output}
|
--output ${output}
|
||||||
--sections ${CMAKE_BINARY_DIR}/ldgen.section_infos
|
--kconfig ${ROOT_KCONFIG}
|
||||||
--kconfig ${IDF_PATH}/Kconfig
|
|
||||||
--env "COMPONENT_KCONFIGS=${COMPONENT_KCONFIGS}"
|
--env "COMPONENT_KCONFIGS=${COMPONENT_KCONFIGS}"
|
||||||
--env "COMPONENT_KCONFIGS_PROJBUILD=${COMPONENT_KCONFIGS_PROJBUILD}"
|
--env "COMPONENT_KCONFIGS_PROJBUILD=${COMPONENT_KCONFIGS_PROJBUILD}"
|
||||||
--env "IDF_CMAKE=y"
|
--env "IDF_CMAKE=y"
|
||||||
--env "IDF_PATH=${IDF_PATH}"
|
--env "IDF_PATH=${IDF_PATH}"
|
||||||
--env "IDF_TARGET=${IDF_TARGET}"
|
--env "IDF_TARGET=${IDF_TARGET}"
|
||||||
DEPENDS ${template} $<TARGET_PROPERTY:ldgen,FRAGMENT_FILES> ${SDKCONFIG}
|
--libraries-file ${CMAKE_BINARY_DIR}/ldgen_libraries
|
||||||
ldgen_section_infos
|
--objdump ${CMAKE_OBJDUMP}
|
||||||
|
DEPENDS ${template} $<TARGET_PROPERTY:ldgen,FRAGMENT_FILES>
|
||||||
|
$<TARGET_PROPERTY:ldgen,LIBRARIES> ${SDKCONFIG}
|
||||||
)
|
)
|
||||||
|
|
||||||
get_filename_component(output_name ${output} NAME)
|
get_filename_component(output_name ${output} NAME)
|
||||||
|
@ -74,9 +71,9 @@ function(ldgen_process_template template output)
|
||||||
add_dependencies(ldgen ldgen_${output_name}_script)
|
add_dependencies(ldgen ldgen_${output_name}_script)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# ldgen_create_commands
|
# ldgen_add_dependencies
|
||||||
#
|
#
|
||||||
# Create the command to generate the output scripts from templates presented.
|
# Add dependency of project executable to ldgen custom target.
|
||||||
function(ldgen_add_dependencies)
|
function(ldgen_add_dependencies)
|
||||||
if(IDF_PROJECT_EXECUTABLE)
|
if(IDF_PROJECT_EXECUTABLE)
|
||||||
add_dependencies(${IDF_PROJECT_EXECUTABLE} ldgen)
|
add_dependencies(${IDF_PROJECT_EXECUTABLE} ldgen)
|
||||||
|
|
|
@ -573,8 +573,8 @@ class SectionsInfo(dict):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sections = dict()
|
self.sections = dict()
|
||||||
|
|
||||||
def add_sections_info(self, sections_info_file):
|
def add_sections_info(self, sections_info_dump):
|
||||||
first_line = sections_info_file.readline()
|
first_line = sections_info_dump.readline()
|
||||||
|
|
||||||
archive_path = (Literal("In archive").suppress() +
|
archive_path = (Literal("In archive").suppress() +
|
||||||
# trim the last character from archive_path, :
|
# trim the last character from archive_path, :
|
||||||
|
@ -587,10 +587,10 @@ class SectionsInfo(dict):
|
||||||
try:
|
try:
|
||||||
results = parser.parseString(first_line)
|
results = parser.parseString(first_line)
|
||||||
except ParseException as p:
|
except ParseException as p:
|
||||||
raise ParseException("File " + sections_info_file.name + " is not a valid sections info file. " + p.message)
|
raise ParseException("Parsing sections info for library " + sections_info_dump.name + " failed. " + p.message)
|
||||||
|
|
||||||
archive = os.path.basename(results.archive_path)
|
archive = os.path.basename(results.archive_path)
|
||||||
self.sections[archive] = SectionsInfo.__info(sections_info_file.name, sections_info_file.read())
|
self.sections[archive] = SectionsInfo.__info(sections_info_dump.name, sections_info_dump.read())
|
||||||
|
|
||||||
def _get_infos_from_file(self, info):
|
def _get_infos_from_file(self, info):
|
||||||
# Object file line: '{object}: file format elf32-xtensa-le'
|
# Object file line: '{object}: file format elf32-xtensa-le'
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from fragments import FragmentFile
|
from fragments import FragmentFile
|
||||||
from sdkconfig import SDKConfig
|
from sdkconfig import SDKConfig
|
||||||
from generation import GenerationModel, TemplateModel, SectionsInfo
|
from generation import GenerationModel, TemplateModel, SectionsInfo
|
||||||
from ldgen_common import LdGenFailure
|
from ldgen_common import LdGenFailure
|
||||||
from pyparsing import ParseException, ParseFatalException
|
from pyparsing import ParseException, ParseFatalException
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -42,9 +44,9 @@ def main():
|
||||||
nargs="+")
|
nargs="+")
|
||||||
|
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"--sections", "-s",
|
"--libraries-file",
|
||||||
type=argparse.FileType("r"),
|
type=argparse.FileType("r"),
|
||||||
help="Library sections info")
|
help="File that contains the list of libraries in the build")
|
||||||
|
|
||||||
argparser.add_argument(
|
argparser.add_argument(
|
||||||
"--output", "-o",
|
"--output", "-o",
|
||||||
|
@ -64,27 +66,28 @@ def main():
|
||||||
action='append', default=[],
|
action='append', default=[],
|
||||||
help='Environment to set when evaluating the config file', metavar='NAME=VAL')
|
help='Environment to set when evaluating the config file', metavar='NAME=VAL')
|
||||||
|
|
||||||
|
argparser.add_argument(
|
||||||
|
"--objdump",
|
||||||
|
help="Path to toolchain objdump")
|
||||||
|
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
|
|
||||||
input_file = args.input
|
input_file = args.input
|
||||||
fragment_files = [] if not args.fragments else args.fragments
|
fragment_files = [] if not args.fragments else args.fragments
|
||||||
|
libraries_file = args.libraries_file
|
||||||
config_file = args.config
|
config_file = args.config
|
||||||
output_path = args.output
|
output_path = args.output
|
||||||
kconfig_file = args.kconfig
|
kconfig_file = args.kconfig
|
||||||
sections = args.sections
|
objdump = args.objdump
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sections_infos = SectionsInfo()
|
sections_infos = SectionsInfo()
|
||||||
|
for library in libraries_file:
|
||||||
if sections:
|
library = library.strip()
|
||||||
section_info_contents = [s.strip() for s in sections.read().split("\n")]
|
if library:
|
||||||
section_info_contents = [s for s in section_info_contents if s]
|
dump = StringIO(subprocess.check_output([objdump, "-h", library]).decode())
|
||||||
else:
|
dump.name = library
|
||||||
section_info_contents = []
|
sections_infos.add_sections_info(dump)
|
||||||
|
|
||||||
for sections_info_file in section_info_contents:
|
|
||||||
with open(sections_info_file) as sections_info_file_obj:
|
|
||||||
sections_infos.add_sections_info(sections_info_file_obj)
|
|
||||||
|
|
||||||
generation_model = GenerationModel()
|
generation_model = GenerationModel()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue