Не думал, что буду здесь когда-либо спрашивать про undefined reference, ибо джуниором себя уже не считаю, но тем не менее придётся. Убедительно прошу не ставить дубликат на известный здесь вопрос, я пытался разобраться и привёл здесь максимум информации.
Начнём с того, что у меня специфическая аппаратная платформа: NMC4. SDK скачан с сайта разработчика и установлен без проблем. При компиляции возникает ошибка линкера:
nmc-g++ main.o -mnmc4 -fexceptions "D:\lab\NMC\nmpp\lib\libnmpp-nmc4d.a" "D:\lab\NMC\hal\lib\libhal-mc12101.a" -o FixPoint /cygdrive/c/Program Files/Module/NMC-SDK/nmc4-ide/lib/gcc/nmc/4.8.3/../../../../nmc/lib/nmc4/libc.a(lib_a-timesr.o): In function `__times_r': (.text.__times_r+0xd): undefined reference to `__times'
Символ __times определён в библиотеке libc.a. Вывод nm:
U __times_r
lib_a-systimes.o:
U __times_r
00000000 T _times
lib_a-timesr.o:
U __times
00000000 T __times_r
Библиотека libc.a подключается автоматически тулчейном, но при принудительном подключении её в настройках компилятора ситуация не меняется. Надо полагать, что эту библиотеку линкер видит: ведь на остальные символы из этой библиотеки он не ругается.
Библиотека libc.a существует только в релизной версии. Попытка смены конфигурации проекта с Debug на Release результатов не дала.
Попытка определения символа __times в своём коде
int __times;
также результата не дала. Я же правильно понимаю, что без модификаторов доступа символы, объявленные в c-файлах имеют публичное связывание?
Техподдержка пока молчит.
/*
* main.cpp
*
* Created on: 9 . 2021 .
* Author: Alouette
*/
#include "nmpp.h"
#include <iostream>
#define SIZE 64
//Вот эта строка, предложенная Fat-Zer, решает проблему, но использовать её - не лучшая идея
//extern "C" int _times(struct tms *buf) { return -1; }
int main()
{
//Если закомментировать выделение памяти, то программа компилируется.
//Но запускать тогда нет смысла.
//Видимо, вызов __times спрятался где-то в недрах функции nmppsMalloc_8s.
nm8s *vec1 = (nm8s*)nmppsMalloc_8s(SIZE);
nm8s *vec2 = (nm8s*)nmppsMalloc_8s(SIZE);
nm8s *result = (nm8s*)nmppsMalloc_8s(SIZE);
nmppsRandUniform_8s(vec1, SIZE);
nmppsRandUniform_8s(vec2, SIZE);
nmppsAdd_8s(vec1, vec2, result, SIZE);
for (int i = 0; i < SIZE; i++)
{
std::cout << nmppsGet_8s(vec1, i) << "+" << nmppsGet_8s(vec2, i) << "=" << nmppsGet_8s(result, i) << std::endl;
}
std::cout.flush();
nmppsFree(vec1);
nmppsFree(vec2);
nmppsFree(result);
return 0;
}
nm'а__timesкак раз не определён (U) – Fat-Zer Mar 26 '21 at 19:54extern "C" int _times(struct tms *buf) { return -1; }... количество подчёркиваний определи по вкусу... – Fat-Zer Mar 26 '21 at 20:40__times, а при добавлении символа_timesлинкер больше не ругается? Разве символ подчёркивания какой-то особенный? p.s. Сегодня получил встречный вопрос от техподдержки. Как только что-то выясним, отпишусь. – maestro Mar 27 '21 at 12:57_часто добавляется к именам символов компилятором по умолчанию (см.-fleading-underscoreдля gcc)... учитывая, что в выводе nm'а у тебя это так для всех (по крайней мере приведённых) символов, то логично было предположить, что это как раз такой случай... – Fat-Zer Mar 27 '21 at 14:34newlibc, а он требует самостоятельного определения «Системных вызовов» для определённых действий (неплохой блогпост по теме). В принципе это правильное решение, но другой вопрос, что именно ты там такого делаешь, что потребовало вызоваtimes(именно для этого нужно было привести [mcve]: это просто из-за инициализации плюсового рантайма или там что-то более специфичное) и можно ли без этого обойтись... – Fat-Zer Mar 27 '21 at 14:36_timesспрятан где-то в недрах используемых функций. – maestro Mar 27 '21 at 15:20nmpps*ониclock()вызывают... скорей всего это какой-то код для профайлинга... в релиз он попадать по идее не должен, но почему-то они его оставили... в общем, что с этим делать лучше у них спросить... ЗЫ: на всякий пожарный, дисклеймер: я не знаком с этой архитектурой и не так хорошо знаком с применением newlib на разнообразных архитектурах, так что все мои замечания чисто умозрительные... – Fat-Zer Mar 29 '21 at 15:56