Почему привязка файла .cc работает в make-файле, а привязка файла .c — нет?

Я работаю над довольно большим Makefile из репозитория tensorflow, и мне нужно добавить ссылку на файл.

После некоторой отладки ошибки ссылки я обнаружил, что если мой файл заканчивается на .cc, то ошибка ссылки исчезает, тогда как при ссылке на файл .c появляется ошибка (содержимое файла остается прежним).

Я связываю файл в файле Makefile.inc:

.
.
.
FL_SRCS := \
tensorflow/lite/vis_mi/main.cc \
myFunctions.c \ -->>>>IF I CHANGE THE FILENAME TO myFunctions.cc and link to this .cc file here, it works!!
.
.
.
# Builds a standalone binary.
$(eval $(call vis_test,vis_mi,\
$(FL_SRCS),$(FL_HDRS)))

Ошибка ссылки при использовании окончания .c заканчивается:

tensorflow/lite/vis_mi/main.o: In function `main':
tensorflow/lite/vis_mi/main.cc:183: undefined reference to `printMsg()'
../downloads/gcc_embedded/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: link errors found, deleting executable `tensorflow/lite/vis_mi'
collect2: error: ld returned 1 exit status
gmake: *** [tensorflow/lite/vis_mi/Makefile.inc:578: tensorflow/lite/vis_mi/bin/micro_speech] Error 1

Код файла .c:

#include <stdio.h>
#include "myFunctions.h"


void printMsg(){
    //do something here
}

И заголовочный файл:

#ifndef MYFUNCTIONS_H
#define MYFUNCTIONS_H

void printMsg();
#endif /* MYFUNCTIONS_H */

Как я могу включить файл, оканчивающийся на .c? Makefiles для меня довольно новы, и я не хотел включать все детали, и если вам нужны какие-либо дополнительные сведения из Makefile, чтобы ответить на этот вопрос, я буду рад отредактировать свой пост.


person user2212461    schedule 09.12.2019    source источник
comment
Расширение файла сообщает make, следует ли обрабатывать файл как код C или код C++. Это изменяет компилятор, флаги, используемые переменные make и т. д. gcc.gnu .org/onlinedocs/gcc/Overall-Options.html   -  person kaylum    schedule 10.12.2019
comment
Итак, ваш код на самом деле C или C++? Если это C++, то нет смысла использовать расширение .c, так как это только запутает всех.   -  person kaylum    schedule 10.12.2019
comment
@kaylum Это код C   -  person user2212461    schedule 10.12.2019
comment
И все приложение, включая библиотеки, C? Если это так, то нам потребуется больше деталей, включая фактические ошибки, правила и переменные make-файла и т. д. Я дал вам то, что делает изменение расширения, но не могу предложить ничего сверх этого с данной информацией.   -  person kaylum    schedule 10.12.2019
comment
Думаю, нужно больше информации. Можно предположить, что в вашем make-файле есть правило, похожее на %.o: %.cc $(CXX) -xc++ -c $< -o $@. Но нет для файлов c.   -  person hko    schedule 10.12.2019
comment
Если make-файлы для вас новы, я призываю вас избегать использования таких сложных и продвинутых возможностей, как eval и call. Почему бы просто не написать простое правило и заставить его работать? Мы ничем не можем помочь, так как все важные части make-файла скрыты за этими расширенными функциями.   -  person MadScientist    schedule 10.12.2019
comment
Один файл компилируется как C++ (main.cc), а другой как C (myFunctions.c). Это не будет работать без изменений кода. Если весь код действительно написан на C, измените main.cc на main.c.   -  person kaylum    schedule 10.12.2019
comment
Если вам нужно расширение .c, вам, вероятно, придется узнать о extern "C" в C++ и о том, как его использовать при вызове кода C.   -  person Jonathan Leffler    schedule 10.12.2019


Ответы (1)


Разрешение имен для функций C и C++ различается. Иногда это вызывает проблемы с кодом "C", который также является допустимым "C++". Например:

int foo(int x) { return x+1 } ;

Код создаст функцию с именем 'foo' при компиляции как "C" и создаст функцию с именем '_Z3fooi' при компиляции как C++. Декодирование имени C++ (с использованием c++filt) покажет foo(int). Причина различия в том, что C++ поддерживает полиморфные функции (и методы), так что имена функций также определяют тип их параметров.

Правильным решением является выбор языка кода. C++ и C — это разные языки, и хотя можно написать код, который будет работать для обоих, это ограничит возможности использования возможностей каждой функции.

Важное ограничение: если проект содержит код как на C, так и на C++, важно помнить, что между языками могут вызываться только функции, соответствующие соглашениям "C". Обычно это реализуется директивой extern "C" и директивой #ifdef __cplusplus:

Подробнее: https://www.thegeekstuff.com/2013/01/mix-c-and-cpp/ Как вызвать C++ функция из C? Вызов функции C из кода C++

person dash-o    schedule 10.12.2019