Как скомпилировать проект C с более чем одной основной функцией? - PullRequest
10 голосов
/ 21 мая 2010

Я новичок в C, а сейчас читаю какой-то учебник и собираюсь применить его примеры.

Проблема в том, что всякий раз, когда я создаю новый проект и пытаюсь поместить более одного файла, который содержит основную функцию, компоновщик (как я объясняю, говоря:

/home/mohammed/tmp/abcd/main.c:4: multiple definition of `main'

(Кстати, я использовал много IDE, MonoDevelop, QT creator, VS2010, Codebloks, ...) В настоящее время я использую QT Creator. Кажется, это очень хорошая среда разработки.

Итак, нет решения для решения такой проблемы ??

EDIT:

Я спрашиваю, потому что я нахожусь в стадии обучения, и сейчас не занимаюсь настоящим программированием. Мне просто нужен простой способ создания программ на C без необходимости создавать отдельный проект для каждого примера книги. В то же время я не хочу использовать командную строку Gedit / VI +.

Итак, нет ли способа очистить проект, а затем скомпилировать - просто - один файл, который мне нужно запустить ??? Кстати, в JAVA мы можем запустить программу, которая содержит более одного основного (IDE дает мне выбор среди них)

Ответы [ 14 ]

10 голосов
/ 21 мая 2010

Что вы пытаетесь сделать с несколькими main функциями?

Если вы пытаетесь скомпилировать несколько разных программ одновременно, вам нужно скомпилировать каждую из них отдельно (т. Е. Только одну main на программу).

Если вы пытаетесь скомпилировать одну программу и хотите запустить несколько main функций all , вы не сможете. Вам нужно указать только один main и переименовать остальные в другое (и вызывать их из единственного main в том порядке, в котором вы хотите их запускать).

Если вы пытаетесь использовать только одну из функций main в качестве единой точки входа в вашу программу и игнорируете другие, то вам не следует включать файлы вместе с другими main при связывании. Я предлагаю помещать каждый main в отдельный файл, если вы хотите сохранить их, и включать только один из этих основных файлов при компоновке / компиляции.

Если вы получили эту ошибку по ошибке, возможно, вы что-то не так делаете с проектом в вашей IDE. Возможно, вы случайно пытаетесь собрать несколько разных программ в одну? Возможно, вам потребуется указать каждый файл, содержащий main, в качестве отдельного продукта сборки. C не похож на Java, где вы можете поместить main метод внутри каждого класса и указать, какой из них вызывать; main в C является глобальным именем.

5 голосов
/ 21 мая 2010

Вы не можете иметь более одной точки входа в вашем приложении. Когда запускается последний исполняемый файл, вызывается функция точки входа (основная) . И этот не может быть двусмысленным.

Так что, если вы хотите назвать их один за другим, вы можете связать их так:

void main1() {} /* Note that these aren't called main. */
void main2() {}
...

int main(int argc, char* argv[]) {
    main1();
    main2();
    return 0;
}

Вы можете даже вызывать их, используя потоки (например, boost.Thread), чтобы они работали параллельно. Но нельзя связать несколько функций с именем main.

Если вы вместо этого хотите, чтобы они были отдельными программами, вам нужно будет связать их отдельно.

2 голосов
/ 07 июля 2016

В одном проекте может быть несколько основных, если каждому основному будет соответствовать свой исполняемый файл в дереве каталогов сборки.

В следующем примере используется CMake, я не знаю, можно ли это сделать с помощью другого программного обеспечения менеджера процессов сборки.

Сохраните следующие два файла .cpp в папке с именем source и назовите их square_root.cpp и power_of_two.cpp:

square_root.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main (int argc, char *argv[])
{

  if (argc < 2) {
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
  }

  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);

  return 0;
}

power_of_two.cpp:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main (int argc, char *argv[])

{
  if (argc < 2) {
      fprintf(stdout,"Usage: %s number\n",argv[0]);
      return 1;
  }

  double inputValue = atof(argv[1]);
  double outputValue = inputValue*inputValue;

  fprintf(stdout,"The power of two of %g is %g\n",
          inputValue, outputValue);

  return 0;
}

Обратите внимание, что они оба содержат метод main. Затем в той же папке добавьте .txt с именем CmakeLists.txt: он сообщит компилятору количество исполняемых файлов, как их вызвать и где найти основные (ие) файлы.

CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (Square_and_Power)
add_executable(Square2 square_root.cpp)
add_executable(Power2 power_of_two.cpp)

Создайте новую папку с именем build в том же корне исходного кода, а затем используйте cmake для настройки и генерации. Посмотрите на структуру папок, созданных в сборке папок. Откройте терминал в сборке и введите make .

 →  make
[ 50%] Built target Power2
Scanning dependencies of target Square2
[ 75%] Building CXX object CMakeFiles/Square2.dir/square_root.cpp.o
[100%] Linking CXX executable Square2
[100%] Built target Square2

Если ошибок не возникнет, у вас будет два исполняемых файла: Square2 и Power2.

→  ./Square2 5
The square root of 5 is 2.23607
 →  ./Power2 5
The power of two of 5 is 25

Итак, у вас есть один и тот же проект с двумя сетевыми системами, который скомпилировал два разных приложения. Два файла cpp могут затем использовать один и тот же заголовок и дополнительные методы в других файлах .cpp или .h в проекте. Предлагаю также взглянуть на учебник по cmake https://cmake.org/cmake-tutorial/ Могут быть и другие методы для получения похожих, если не одинаковых результатов, но я не знаю ни одного. Надеюсь, что другой пользователь внесет свой вклад в эту тему!

2 голосов
/ 21 мая 2010

Как уже говорили многие, у вас может быть только одна основная программа. Вы не хотите испытывать трудности, связанные с созданием нового проекта для каждого примера, когда вы читаете книгу. Это понятно, но вам придется сделать это в основном. Я вижу две альтернативы:

  1. Используйте новую функцию проекта в вашей IDE (например, VS2010). Это сделает всю тяжелую работу за вас. Вы всегда можете удалить их позже.
  2. Если вы не хотите хранить код, просто очистите файл (или даже функцию main ()) и используйте его повторно. С примерами из книг вы, вероятно, никогда не будете пересматривать код в любом случае, поэтому достаточно просто удалить его.
2 голосов
/ 21 мая 2010

Каждая программа должна иметь ровно одну основную функцию. Тем не менее, main может вызывать любую функцию, которую вы хотите (включая себя, хотя это может сбивать с толку). Таким образом, вы должны разбить программу на логические части.

1 голос
/ 26 мая 2010

На самом деле, я считаю, что Dev-C ++ поддерживает работу с несколькими основными файлами, которые не являются частью какого-либо проекта, поэтому я могу создать столько файлов, сколько мне нужно.

Спасибо всем, кто здесь корпоративный :) Гук удачи для всех.

Кроме того, для Linux / win я обнаружил, что Code :: Blocks делает этот трюк. спасибо.

0 голосов
/ 27 июня 2016

Лучшее решение, которое я мог найти, было на Eclipse, создающем проекты каждый раз для запуска одного файла? у него есть несколько альтернатив, чем создание нового проекта для каждой программы.

0 голосов
/ 07 ноября 2013

В QtCreator вы можете щелкнуть правой кнопкой мыши файл и выбрать опцию «Компилировать», которая компилирует только выбранный файл и необходимые зависимости. Поэтому, если вы скомпилируете один из ваших основных файлов, как этот, и этот файл не включает в себя никакой другой основной файл, это должно сработать.

0 голосов
/ 21 октября 2012

Ну, я думаю, что QtCreator - отличная IDE.

Для обучения и тестирования было бы неплохо иметь возможность иметь несколько для простоты использования, однако, как объяснялось ранее, вы можете иметь только один основной потому что так определяется проект в файлах QTcreator / .pro qmake.

Вы можете создать несколько целей в файлах pro или make / CMAKE.

Но для тестирования я сделал это в файле .pro для проекта.


MAIN = simpletree_test.c

SOURCES += \
    $$MAIN \
    simpletree.c \
    graph_tree.c \
    redblacktreenode.c \
    redblacktree.c \
    redblack.c \
    pointers.c

HEADERS += \
    simpletree.h \
    graph_tree.h \
    redblacktreenode.h \
    redblacktree.h \
    redblack.h \
    pointer_manipulator.h

message("The project contains the following files:")
message($$SOURCES)

Так что я просто обмениваю основное имя файла в переменной с именем MAIN в файле pro. использовать его в переменной SOURCES.

Как видите, я тестирую несколько реализаций деревьев. Прямо сейчас тестируем простой вариант деревьев, где я тестирую новую реализацию для поиска определенного узла, прежде чем тестировать их на сбалансированном дереве.

Однако этот метод не совершенен, поскольку вы не можете иметь одинаковые имена для функций и т. Д. И через некоторое время мне может быть сложно найти новые имена для find_node () или traverse_tree ()

0 голосов
/ 21 мая 2010

Если вы используете компоновщик MS, используйте опцию / FORCE: MULTIPLE. Победит первый главный символ. Не уверен, что опция для других линкеров.

...