1

For the purpose of learning I want to have a project with multiple source files and each has it's own main function. How it is possible to achieve this? What I'm trying to do is to have all my C files in the same project and selectively compile those I'm currently working on. Or better yet, supply the name of the file as an argument to the program so it can execute it:

For instance in my main.c I'd like to have (where sample*_main functions are in different files):

int main(int argc, char ** argv) {
    if (argc > 0)  {
        if (strstr(argv[0], "sample1")) return sample1_main(argc, argv);
        else if (strstr(argv[0], "sample2")) return sample2_main(argc, argv);
// etc...
    }
printf("Not sure what I should run.\n");
return -1;
}

Then execute the program like so: main.exe sample1

The issue I'm having is "multiple definition of" error when compiling such type of project, when some of functions share names between sample*.c files.

4
  • I think you can achieve this using make Commented Jul 5, 2013 at 5:14
  • You can use macro definitions for main functions in other files. when compiled as library, define it as sample1_main otherwise as main Commented Jul 5, 2013 at 5:16
  • @VoidPointer, can you provide simple code pls? Commented Jul 10, 2013 at 1:59
  • @DimonBuzermann hope you got what you need Commented Jul 10, 2013 at 13:32

3 Answers 3

1

You seem to be on the right trail.

To reach your goal you could go the following way:

  1. rename the several main()s as by your example code to sample1_main(), sample2_main() ... (this avoids the multiple definition of error btw)
  2. leave the main() from your post as is
  3. modify your makefile in such a way, that depending on which sample you want to run, the executable built is called sample1, sample2, ... (for gcc the option -o specifies the name of the executable)
  4. call the executable by its name, that is sample1 or sample2 or .... There is no need to pass ayn parameters.

That's it! :-)

The reason for this behaviuor is that argv[0] is the name of the executable itself.

Sign up to request clarification or add additional context in comments.

Comments

0

It sounds like you want to be able to select the "main" function that executes at runtime, rather than compile-time. One way to do this is to define them as separate "entry point" functions and then have a means to select the one that runs in your main function based on the command line arguments.

So you would define main.c, sample1.c, sample2.c, etc. and in main.c you would have something like this:

int main(int argc, char **argv) {
  char *methodToExecute;

  if (argc < 2) {
    printf("usage: main.exe <sample_name>\n");
    exit(-1);
  }

  methodToExecute = argv[1]; /* argv[0] is 'main.exe' */

  if (strcmp(methodToExecute, "sample1") == 0) {
    return sample1();
  }
  else if (strcmp(methodToExecute, "sample2") == 0) {
    return sample2();
  }

  /* etc. */
  else {
    printf("method not found: %s\n", methodToExecute);
    exit(-1);
  }
}

2 Comments

Thanks for a suggestion Peter. I think this is exactly what I'm doing. But as I pointed out if sample1.c and sample2.c contain the same identifiers (which is my case) then I get "multiple definition of" error in compile time.
If you have one or more symbols (identifiers) that must be referenced in different files, then you need to declare them with the extern modifier in a header file and include that file in all files that need to reference the symbol. Then you define the variable in only one location and that common definition is referenced by any code that needs to access the symbol.
0

You can use macro for main functions in other files. When compiled as library, define it as sample1_main (using gcc -D option) otherwise as main. Try something like,

sm1.c:

#include <stdio.h>

#ifndef S1_MAIN
 #define S1_MAIN main
#endif

int S1_MAIN( int argc, char ** argv)
{

    printf( "This is (sample1_main)\n" );
    return 0;
}

sm2.c:

#include <stdio.h>

#ifndef S2_MAIN
 #define S2_MAIN main
#endif

int S2_MAIN( int argc, char ** argv)
{

    printf( "This is (sample2_main)\n" );
    return 0;
}

main.c:

#include <stdio.h>
#include <string.h>

int sample1_main(int , char ** );
int sample2_main(int , char ** );

int main(int argc, char ** argv)
{
    if (argc > 1)
    {
            if (strstr(argv[1], "sample1")) return sample1_main(argc, argv);
            else if (strstr(argv[1], "sample2")) return sample2_main(argc, argv);
    }
    printf("Not sure what I should run.\n");
    return 0;
}

Compilation: (as single binary)

gcc -Wall -DS1_MAIN="sample1_main" -DS2_MAIN="sample2_main" main.c sm1.c sm2.c -o main

./main
Not sure what I should run.
./main sample1
This is (sample1_main)
./main sample2
This is (sample2_main)

Compilation: (as separate binaries)

gcc -Wall sm2.c -o sm2
gcc -Wall sm1.c -o sm1
./sm1
This is (sample1_main)
./sm2
This is (sample2_main)

Note: I have fixed main file to check the command line arguments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.