LINUX.ORG.RU

Скрыть некоторые функции

 


0

1

В одном из своих велосипедов я хочу использовать чужой файл, в котором сказано

You are permitted to copy and distribute this program as much as you want, as long as you leave the source code, including this comments section, intact and unmodified.

Т.к. оно у меня болтается на всяких сосфоржах и гуглокодах, нарушать лицензию не хочу.

Оригинальный файл — самостоятельная утилита. Я же хочу выкинуть из нее функции usage и main и использовать у себя.

Сделал файл-обертку am.c, в который поместил:

#define main nooperation
#include "airmass.c"
#undef main

// и дальше - замена main, которая вызывается из моего велосипеда

При этом получаю, что (gcc -Werror am.c -c) отрабатывает без проблем, но make выдает кучу ошибок:

В функции <<nooperation>>:
ошибка: <<M_PI>> undeclared (first use in this function)
ошибка: <<it>> is static but declared in inline function <<trapzd>> which is not static [-Werror]
…
И т.п.

Как мне включить целиком этот чужой файл в свой, чтобы выбросить ненужные функции и вставить свое?

============================================================

Решение подсказали io и Q3164. Несмотря на некоторые костыли (с проблемой с M_PI я так и не разобрался) вот так работает:

#define __USE_XOPEN
#include <math.h>
static int main(int argc, char *argv[]) __attribute((unused));
static void usage(void) __attribute((unused));
#define inline
#include "airmass.c"
#undef inline

void airmass(
…

Компилировать не с -std=c99, а std=gnu99.

☆☆☆☆☆

Последнее исправление: Eddy_Em (всего исправлений: 4)

Допустим, чужой файл зовётся foreign.c и в нём объявлена int main(int argc, char *argv[]); Тогда ты делаешь обёртку foreign-wrapper.c:

static int main(int argc, char *argv[]);
#include "foreign.c"
И компилируешь со своим проектом уже обёртку.

i-rinat ★★★★★
()

M_PI, unused и static м.б. во внешнем файле

extern int M_PI();
static int abc(void) __attribute((unused));

int abc()
{
        return M_PI();
}

Компилируем с -O1 и выше: gcc -S -O1 unused.c -Wall

	.file	"unused.c"
	.ident	"GCC: (GNU) 4.4.5 20101112 (Red Hat 4.4.5-2)"
	.section	.note.GNU-stack,"",@progbits

Функция исчезла вместе с зависимостями. Сообщений и ошибок нет.

io ★★
()
Ответ на: комментарий от io

M_PI();

M_PI — макрос, определенный в math.h. И почему его gcc не видит — парадокс.

Eddy_Em ☆☆☆☆☆
() автор топика

Хрень какая-то непонятная. Вот так компилится без проблем:

#define M_PI 3.14159265358979323846
static int main(int argc, char *argv[]) __attribute((unused));
static void usage(void) __attribute((unused));
#define inline
#include "airmass.c"
#undef inline
А если уберу первую строчку и вставлю #include <math.h> (в файле airmass.c она, кстати, есть), то фигвам: ругается на M_PI.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Какие-то проблемы с define-ами влияющими на доступность имен из math.h Тривиальный пример:

#include <features.h>
#undef __USE_BSD
#include <math.h>

static int abc(void) __attribute((unused));

int abc()
{
	return M_PI;
}

Имеем:

gcc -S unused.c 
unused.c: In function ‘abc’:
unused.c:9: error: ‘M_PI’ undeclared (first use in this function)
unused.c:9: error: (Each undeclared identifier is reported only once
unused.c:9: error: for each function it appears in.)

В math.h проверочка есть, которая и мешает (#if defined __USE_BSD || defined __USE_XOPEN). Можно попробовать во внешнем файле тоже поставить #include <math.h> (внутренний include мешать уже не будет).

io ★★
()
Ответ на: комментарий от Eddy_Em

Однако у меня такой вариант пролетает нормально:

#include <math.h>
#include <features.h>
#undef __USE_BSD
#include <math.h>

static int abc(void) __attribute((unused));

int abc()
{
        return M_PI;
}

Что еще стоит перед include <math.h> ?

Рекомендую попробовать добавить ключи -E -dD и посмотреть какой файл будет сгенерирован.

io ★★
()
Ответ на: комментарий от io

С этими ключами вот такие матюги:

make
Linking C executable apogee_control
CMakeFiles/apogee_control.dir/takepic.c.o: file not recognized: File format not recognized

Да хрен с ним, M_PI: и так работает.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Вообще-то не ожидалось, что команда будет запущена под make-ом, т.к. должен был сгенерироваться текстовый файл. Лучше было выдать одну команду и без -o file. Т.ч. диагностика про CMakeFiles/apogee_control.dir/takepic.c.o корректная. Получился не объектный, а текстовый файл который можно было проанализировать.

io ★★
()
Ответ на: комментарий от io

Сделал. Получаю (с принудиловкой):

<skipped>
# 349 "/usr/include/math.h" 3 4
<skipped>
#define M_PI 3.14159265358979323846
<skipped>
#define M_PI 3.14159265358979323846
<skipped>
# 795 "airmass.c" 2
# 804 "airmass.c"
#define DEG2RAD (M_PI/180.)
<skipped>
sinz=sin(z*(3.14159265358979323846/180.));

Без принудительного #define все тоже в порядке:

 sinz=sin(z*(3.14159265358979323846/180.));
А вот make матерится

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Это файл .o который получен под make-ом или сгенерированный отдельно? Если отдельно, значит make либо запускает другую команду, либо устанавливает дикий environment. Забавный случай.

io ★★
()
Ответ на: комментарий от io

Вот:

[ 14%] Building C object CMakeFiles/apogee_control.dir/am.c.o
/usr/bin/gcc  -DUSE_BTA -DLOCALEDIR=\"/usr/share/locale\" -DPACKAGE_VERSION=\"0.2.0\" -DGETTEXT_PACKAGE=\"apogee_control\" -I/usr/local/include/libapogee    -O3 -Wall -Werror -W -std=c99 -o CMakeFiles/apogee_control.dir/am.c.o   -c /home/eddy/Docs/SAO/Google_code/apogee-control/am.c
In file included from /home/eddy/Docs/SAO/Google_code/apogee-control/am.c:7:0:
/home/eddy/Docs/SAO/Google_code/apogee-control/airmass.c: В функции <<main>>:
/home/eddy/Docs/SAO/Google_code/apogee-control/airmass.c:1083:15: ошибка: <<M_PI>> undeclared (first use in this function)

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Т.е. это M_PI именно в выводе отдельной команды запущенной в правильной директории? Или директория м.б. другой? Нет ли «лишних» math.h, feature.h и т.п. в /usr/local/include и т.п.? Можно добавить ключик -v (файлов в отличие от -E не сломает) и сравнить выдачу make с выдачей при запуске отдельной командой.

io ★★
()
Ответ на: комментарий от io

Я даже не представляю себе, как при помощи cmake заставить make генерировать вспомогательные (обработанные лишь препроцессором) файлы.

P.S. Если кому интересно, проект можно найти здесь (это — последний коммит, без сегодняшних правок).

Eddy_Em ☆☆☆☆☆
() автор топика
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Проблема возникает из-за ключа -std=c99 который автоматически определяет __STRICT_ANSI__ и поехало. Такой код работает:

#define _BSD_SOURCE
#include <math.h>
//#define M_PI 3.14159265358979323846
static int main(int argc, char *argv[]) __attribute((unused));
static void usage(void) __attribute((unused));
#define inline
...

Можно также использовать #undef __STRICT_ANSI__ до math.h или убрать -std=c99

io ★★
()

You are permitted to copy and distribute this program as much as you want, as long as you leave the source code, including this comments section, intact and unmodified.

Эмм, как бы это можно по-разному понять. Очень вероятно, что имелось в виду «this comment section intact and unmodified», а не весь сорс. Я бы советовал обратиться к автору.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.