Search code examples
ccompilationprogram-entry-point

Compile C code without it's main function


So I have several files for a University Project I'm working on; each file has several functions and a main function for testing purposes. However some of the files need to use functions from the others which gives linker complaints about multiple main declarations as to be expected. I was wondering if there was a way to compile these files to an object file without compiling the main function along the way, basically stripping out main to leave only the usable functions.

An example (not one of my actual files which are quite large), for each I'm assuming the existence of a header file which contains a declaration of foo and bar respectively:

//File foo.c
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"

int foo(int x, int y)
{
    return x + y;
}

//Assumes the user gives 2 integer inputs
int main(int argc, char **argv)
{
    int x, y;
    sscanf(argv[1], "%d", &x);
    sscanf(argv[2], "%d", &y);
    printf("foo(%d, %d) = %d\n", x, y, foo(x,y));
}

//File bar.c
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
#include "bar.h"

int bar(int x, int y, int z);
{
    return foo(x, y) * z;
}

//Assums the user gives 3 integer inputs
int main(int argc, char **argv)
{
    int x, y, z;
    sscanf(argv[1], "%d", &x);
    sscanf(argv[2], "%d", &y);
    sscanf(argv[3], "%d", &z);
    printf("bar(%d, %d, %d) = %d\n", x, y, z, bar(x, y, z));
}

Is it possible to compile foo.c to an object file so that I could call gcc bar.c foo.o and get an executable for bar.c?


Solution

  • You can do an #ifdef on a symbol that you define only if you are compiling the file to generate the "test executable", and not when you use the file along with others; I've seen this being used for quick functional tests on small libraries.

    #include "foo.h"
    
    int foo(int x, int y)
    {
        return x + y;
    }
    
    #ifdef COMPILE_MAIN
    //Assumes the user gives 2 integer inputs
    int main(int argc, char **argv)
    {
        int x, y;
        sscanf(argv[1], "%d", &x);
        sscanf(argv[2], "%d", &y);
        printf("foo(%d, %d) = %d\n", x, y, foo(x,y));
    }
    #endif
    

    Now you can do

    gcc -DCOMPILE_MAIN foo.c -o foo.x
    

    to make an executable foo.x that you can call directly to test foo, and you can do

    gcc foo.c bar.c main.c -o yourapp.x
    

    to make an executable using the other files (including the one with the "real" application main) without complaints of multiply defined symbols.