diff --git a/tools/test_apps/build_system/ldgen_test/CMakeLists.txt b/tools/test_apps/build_system/ldgen_test/CMakeLists.txt new file mode 100644 index 0000000000..cc7567eceb --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/CMakeLists.txt @@ -0,0 +1,15 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ldgen_test) + +idf_build_get_property(python PYTHON) +idf_build_get_property(elf EXECUTABLE) + +add_custom_command( + TARGET ${elf} + POST_BUILD + COMMAND ${python} ${CMAKE_CURRENT_LIST_DIR}/check_placements.py ${CMAKE_OBJDUMP} $ +) diff --git a/tools/test_apps/build_system/ldgen_test/README.txt b/tools/test_apps/build_system/ldgen_test/README.txt new file mode 100644 index 0000000000..adc6d53e2e --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/README.txt @@ -0,0 +1,5 @@ +Runs a build test to check ldgen places libraries, objects and symbols +correctly as specified in the linker fragments. Specifically, this app +tests the placement for the main component, as specified in `main/linker.lf` +The Python script that performs the checks, `check_placements.py`, automatically +runs after the app is built. diff --git a/tools/test_apps/build_system/ldgen_test/check_placements.py b/tools/test_apps/build_system/ldgen_test/check_placements.py new file mode 100644 index 0000000000..21e7ab7606 --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/check_placements.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# Copyright 2020 Espressif Systems (Shanghai) PTE LTD +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Check placements in this test app for main +# specified in main/linker.lf + +import argparse +import subprocess + +from pyparsing import LineEnd, Literal, ParseException, SkipTo, Word, alphanums, hexnums + +argparser = argparse.ArgumentParser() + +argparser.add_argument('objdump') +argparser.add_argument('elf') + +args = argparser.parse_args() + +contents = subprocess.check_output([args.objdump, '-t', args.elf]).decode() + + +def check_location(symbol, expected): + pattern = Word(alphanums + '._').setResultsName('actual') + Word(hexnums) + Literal(symbol) + LineEnd() + pattern = SkipTo(pattern) + pattern + + try: + results = pattern.parseString(contents) + except ParseException: + print("check placement fail: '%s' was not found" % (symbol)) + exit(1) + + if results.actual != expected: + print("check placement fail: '%s' was placed in '%s', not in '%s'" % (symbol, results.actual, expected)) + exit(1) + + print("check placement pass: '%s' was successfully placed in '%s'" % (symbol, results.actual)) + + +# src1:func1 (noflash) - explicit mapping for func2 using 'rtc' scheme +check_location('func1', '.iram0.text') + +# src1:func2 (rtc) - explicit mapping for func2 using 'rtc' scheme +check_location('func2', '.rtc.text') + +# src1 (default) - only func3 in src1 remains that has not been +# mapped using a different scheme +check_location('func3', '.flash.text') + +# * (noflash) - no explicit mapping for src2 +check_location('func4', '.iram0.text') diff --git a/tools/test_apps/build_system/ldgen_test/main/CMakeLists.txt b/tools/test_apps/build_system/ldgen_test/main/CMakeLists.txt new file mode 100644 index 0000000000..466b45c56c --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "src1.c" "src2.c" "test_main.c" + INCLUDE_DIRS "." + LDFRAGMENTS "linker.lf") diff --git a/tools/test_apps/build_system/ldgen_test/main/component.mk b/tools/test_apps/build_system/ldgen_test/main/component.mk new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/test_apps/build_system/ldgen_test/main/linker.lf b/tools/test_apps/build_system/ldgen_test/main/linker.lf new file mode 100644 index 0000000000..b467f814ae --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/main/linker.lf @@ -0,0 +1,7 @@ +[mapping:main] +archive: libmain.a +entries: + * (noflash) + src1 (default) + src1:func1 (noflash) + src1:func2 (rtc) diff --git a/tools/test_apps/build_system/ldgen_test/main/src1.c b/tools/test_apps/build_system/ldgen_test/main/src1.c new file mode 100644 index 0000000000..c8be4906da --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/main/src1.c @@ -0,0 +1,16 @@ +#include + +void func1(void) +{ + printf("Hello from func1!\n"); +} + +void func2(void) +{ + printf("Hello from func2!\n"); +} + +void func3(void) +{ + printf("Hello from func3!\n"); +} diff --git a/tools/test_apps/build_system/ldgen_test/main/src2.c b/tools/test_apps/build_system/ldgen_test/main/src2.c new file mode 100644 index 0000000000..bdcbee9606 --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/main/src2.c @@ -0,0 +1,6 @@ +#include + +void func4(void) +{ + printf("Hello from func4!\n"); +} diff --git a/tools/test_apps/build_system/ldgen_test/main/test_main.c b/tools/test_apps/build_system/ldgen_test/main/test_main.c new file mode 100644 index 0000000000..37aaa6aecd --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/main/test_main.c @@ -0,0 +1,14 @@ + +extern void func1(void); +extern void func2(void); +extern void func3(void); +extern void func4(void); + + +void app_main(void) +{ + func1(); + func2(); + func3(); + func4(); +}