簡體   English   中英

如何編譯具有多個主函數的C項目?

[英]How to compile a C project with more than one main function?

我是C的新手,現在閱讀一些教科書並開始應用它的例子。

問題是,每當我創建一個新項目並嘗試放置包含main函數的多個文件時,鏈接器(正如我thougt0解釋說的那樣:

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

(順便說一句,我使用了很多IDE,MonoDevelop,QT創建者,VS2010,Codebloks,...)我目前使用QT Creator,它似乎是一個非常好的IDE。

那么,解決這樣的問題沒有辦法解決?

編輯:

我問,因為我正處於學習階段,現在不做真正的編程。 我只需要一種簡單的方法來在C中創建程序,而不必為每個書籍示例創建一個單獨的項目。 同時,我不想使用Gedit / VI +命令行。

那么,有沒有任何方法,如清理項目,然后編譯 - 只需一個文件,我需要運行??? 順便說一句,在JAVA中我們可以運行一個程序,它包含多個主程序(IDE給我選擇)

你想用多個main功能做什么?

如果你正在嘗試編譯一次多個不同的程序,你需要單獨編譯每一個(即只有一個main每程序)。

如果你正在嘗試編譯一個程序,並希望多個main功能的全部運行,你不能。 您只需要指定一個main並將其他main重命名為其他內容(並按照您希望它們運行的​​順序從單個main中調用它們)。

如果您只是嘗試使用其中一個main功能作為程序的單個入口點而忽略其他功能,則在鏈接時不應將文件與其他main包括在一起。 如果您希望保留它們,我建議將每個main放在一個單獨的文件中,並且在鏈接/編譯時只包含其中一個主文件。

如果您錯誤地收到此錯誤,那么您可能在IDE中執行了錯誤的項目。 也許你不小心嘗試將多個不同的程序編譯成一個? 您可能需要將包含main每個文件指定為單獨的構建產品。 C不像Java那樣你可以在每個類中放入一個main方法並指定要調用的方法; C中的main是全局名稱。

您的應用程序中不可能有多個入口點。 啟動最終可執行文件時,將調用入口點函數(main) 這一點不能模棱兩可。

所以,如果你想逐個調用它們,你可以像這樣鏈接它們:

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

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

您甚至可以使用線程(例如boost.Thread)調用它們,以便它們並行運行。 但是你不能將多個名為main函數鏈接在一起。

如果您希望它們分別是單獨的程序,則必須單獨鏈接它們。

每個程序必須只有一個主要功能。 但是,main可以調用你想要的任何函數(包括它自己,雖然這可能會令人困惑)。 因此,您應該將程序分解為邏輯部分。

正如許多人所說,每個程序只能有一個主程序。 在閱讀本書時,您不希望為每個示例創建一個新項目的麻煩。 這是可以理解的,但基本上你必須這樣做。 我看到兩種選擇:

  1. 在IDE中使用新項目功能(如VS2010)。 這將為您完成所有艱苦的工作。 您可以隨時刪除它們。
  2. 如果您不關心代碼,只需清空文件(甚至是main()函數)並重新使用它。 使用書籍示例,您可能永遠不會重新訪問代碼,因此只需刪除它就可以了。

如果每個main將在構建目錄樹中對應不同的可執行文件,則在同一項目中可以有多個main。

以下示例使用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。 然后,在同一個文件夾中,添加一個名為CmakeLists.txt的.txt:它將告訴編譯器可執行文件的數量,如何調用它們以及在哪里找到main(s)。

的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/ 。如果不是相同的結果可能還有其他類似的方法,但我不知道。 希望其他用戶將為此主題做出貢獻!

實際上,我發現Dev-C ++支持處理不屬於任何項目的多個主文件,因此我可以根據需要創建一個運行盡可能多的文件。

謝謝所有在這里合作的人:)祝所有人好運。

此外,對於Linux / win,我發現Code :: Blocks可以做到這一點。 謝謝。

我認為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)

所以我只是在pro文件中交換名為MAIN的變量中的主文件名。 在SOURCES變量中使用它。

正如您所看到的,我測試了幾種樹的實現。 現在正在測試樹的簡單變體,我在測試特定節點的新實現之前,在平衡樹上測試它們。

然而,這個方法並不完美,因為你不能為函數等提供相同的名稱。過了一段時間我很難為find_node()或traverse_tree()創建新的名字。

在QtCreator中,您可以右鍵單擊文件並選擇“編譯”選項,該選項僅編譯所選文件和所需的依賴項。 因此,如果你編譯一個這樣的主文件,並且該文件不包含任何其他主文件,這應該可行。

我猜你的一個IDE會自動創建一個帶有main函數的文件。 檢查周圍是否已經創建了一個。

你不能有多個main定義。 “主要”功能實質上是定義程序的功能。 如果您有多個main副本,您希望執行哪個副本?

你的問題的解決方案是使用庫; 如果你想重用功能,那么你應該創建一個庫,它與程序基本相同,只是它有功能和數據(如程序),它沒有一個叫做“main”的特殊功能,因此沒有“入口點”,執行應該在操作系統雙擊或以其他方式加載時開始。 庫有兩種變體:共享/動態和靜態。 任何人都應該這樣做。 您創建的每個程序都有自己的主要功能,但您可以在不同程序中重復使用您的庫而不會出現任何問題。

現在關於創建庫的實際元素...請參閱我的C ++庫項目模板

正如其他人所說,您的項目可能只有一個主要功能。

你為什么要嘗試多個主要功能? 是因為您將多個小示例程序放入一個項目中,並且每個項目都有一個主要的? 如果是這種情況,您可能需要為每個示例創建一個單獨的項目,以便IDE不會要求編譯器將來自多個示例的源代碼編譯/鏈接到一個程序中。 您的IDE也可能支持像目標這樣的概念,它允許您在一個項目中保留多個相關程序的代碼,而不是選擇實際構建的程序(目標)。 然后,IDE將僅編譯/鏈接該目標中的文件。

嘗試使用static關鍵字,例如:

file1.cpp:

#ifdef RUN_FILE1
#define STATIC static
#else
#define STATIC
#endif

int STATIC main(int argc, char **argv(){}

file2.cpp:

#ifdef RUN_FILE2
#define STATIC static
#else
#define STATIC
#endif

int STATIC main(int argc, char **argv(){}

用於編譯add /DRUN_FILE2/DRUN_FILE1

只是一個想法。

如果您正在使用MS鏈接器,請使用/ FORCE:MULTIPLE鏈接器選項。 遇到的第一個主要符號將獲勝。 不確定其他連接器的選項是什么。

我能找到的最佳解決方案是Eclipse每次創建項目以運行單個文件? 它有一些替代方案,而不是為每個程序創建一個新項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM