LinuxForum.Fans
Тема

Исключить не используемые функции при линковки

Автор: aivs 9 сообщений 2751 просмотров
#314957

Программирую на Си под AVR ATtiny2313, flash памяти у нее 2 килобайта, каждый байт на счету, поэтому требуется тщательно следить, чтобы лишний код не попадал в HEX файл.

У меня была программа состояла из трех файлов:
main.c // основной файл программы
lcd_lib.c // библиотека для работы с LCD экраном HD44780
ds18b20.c // библиотека для работы с термодатчиком ds18b20

листинг main.c

text
#define F_CPU 8000000UL
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/io.h>
#include <stdlib.h>
#include "lcd_lib.c"            // библиотека для работы с LCD HD44780
#include "ds18b20_lib.c" 
.....
void main(void) {
......
}

Компилирую и собираю так:

text
avr-gcc -O2 -Os -mmcu=attiny2313 -o sensor.elf sensor.c

Делаем HEX

text
avr-objcopy -R .eeprom -O ihex sensor.elf sensor.hex

HEX получается 2032 байт, т.е. влезет в 2048 байт flash памяти attiny2313

Затем я решил сделать все красиво и включать в main.c не с файлы, а h файлы.

листинг main.c

text
#define F_CPU 8000000UL
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/io.h>
#include <stdlib.h>
#include "lcd_lib.h"            // библиотека для работы с LCD HD44780
#include "ds18b20_lib.h" 
.....
void main(void) {
......
}

Создаю объектный файл lcd_lib.o:

text
avr-gcc -O2 -Os -mmcu=attiny2313 -std=c99 -c lcd_lib.c  -I /usr/avr/include/

Создаю объектный файл ds18b20_lib.o:

text
avr-gcc -O2 -Os -mmcu=attiny2313 -std=c99 -c ds18b20_lib.c  -I /usr/avr/include/

Создаю объектный файл sensor.elf:

text
avr-gcc -O2 -Os -mmcu=attiny2313 -std=c99 lcd_lib.o ds18b20_lib.o main.c -o sensor.elf

Делаем HEX:

text
avr-objcopy -R .eeprom -O ihex sensor.elf sensor.hex

И вот такой HEX уже не влезает в 2048 байт!!!

Вопрос: В первом варианте, где в main.c подключены lcd_lib.c и ds18b20_lib.с неиспользуемые функции из этих файлов не попадают в результирующий файл?
Какой есть способ на этапе линковки исключить неиспользуемые функции ?

#314967
"aivs⇓" написал:
Вопрос: В первом варианте, где в main.c подключены lcd_lib.c и ds18b20_lib.с неиспользуемые функции из этих файлов не попадают в результирующий файл?Какой есть способ на этапе линковки исключить неиспользуемые функции ?

неиспользуемые функции выкидываются даже на -O1, а на -Os и подавно... [могу ошибаться... лучше проверить objdump'ом]

если в lcd_lib.c есть очень мелкие функций, то они не встраиваются при раздельной компиляции. я бы винил именно это...
для gcc >= 4.6 можно попробовать -flto.

ЗЫ: одновременно -O2 и -Os включать не надо...

#314977
ormorph написал:
тыц не оно?

Оно!

На каких этапах применять оптимизацию, на этапе компиляции:

text
avr-gcc -Os -mmcu=attiny2313 -std=c99 -c lcd_lib.c  -I /usr/avr/include/

Или на этапе линковки:

text
avr-gcc -Os -mmcu=attiny2313 -std=c99 lcd_lib.o ds18b20_lib.o main.o -o sensor.elf
#314990

Оптимизация однозначно применяется на этапе компиляции, по этому для исключения ненужных функций линкером на этапе линковки, нужен все таки параметр -Wl,-gc-sections
чтобы этот параметр работал в процессе линковки, в процессе сборки должны еще применяться параметры -ffunction-sections и -fdata-sections

#315003
"Fat-Zer⇓" написал:
[могу ошибаться... лучше проверить objdump'ом]

Ага проверил неиспользуемые функции все равно остаются))
вот пример код с кучей неиспользуемых функций в одном файле:

Показать
#include <stdio.h>
#include <string.h>

#define BIG_SIZE 0x1000000

int main(int argc, char * argv[])
{
FILE * f;
f = fopen(argv[1], "w");
if (f == NULL)
{
printf("Невозможно создать файл: %s", argv[1]);
return 1;
}
fwrite(argv[1], 1, strlen(argv[1]), f);
fseek(f, BIG_SIZE, SEEK_CUR);
fwrite(argv[1], 1, strlen(argv[1]), f);
fclose(f);
}
int telo()
{
printf("Невозможно создать файл:\n");
}
int telo1()
{
printf("Невозможно создать файл:\n");
}
int tel2()
{
printf("Невозможно создать файл:\n");
}
int tel3()
{
printf("Невозможно создать файл:\n");
}

Работает только -flto, с остальными оптимизациями все эти функции остаются.
с параметром -Wl,-gc-sections бинарник получается меньше.

#315011

У меня тоже при добавлении опций -Wl,-gc-sections и -ffunction-sections и -fdata-sections функции не исключились.
Я взял Makefile из проекта по ссылке

ormorph написал:
тыц не оно?

и уже с этим Makefile все заоптимизировалось нормально, функции исключились.
Буду изучать этот Makefile!

#315015

Хм странно, у меня все ок исключилось, как вы задавали сборку?
я выполнил так:

text
gcc file.c -o file -ffunction-sections -fdata-sections -Wl,-gc-sections
#315593
ormorph написал:
Хм странно, у меня все ок исключилось, как вы задавали сборку?
я выполнил так:
text
gcc file.c -o file -ffunction-sections -fdata-sections -Wl,-gc-sections

А я видимо запятую пропустил -Wl,-gc-sections.
До большого компа доберусь, проверю

Войдите или зарегистрируйтесь, чтобы ответить.