[英]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可以调用你想要的任何函数(包括它自己,虽然这可能会令人困惑)。 因此,您应该将程序分解为逻辑部分。
正如许多人所说,每个程序只能有一个主程序。 在阅读本书时,您不希望为每个示例创建一个新项目的麻烦。 这是可以理解的,但基本上你必须这样做。 我看到两种选择:
如果每个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.