Dealing with double _main in the Fortran code

From time to time it happens that you are forced to work with legacy code. This code might have _main already defined inside. This may happen in case you are trying to link two object files, both, defining _main function.

There is hope!

Let’s say we have a code (legacy one)

! legacy.f90
module liblegacy
    implicit none
    contains
    subroutine hello
        print *,'Hello world!'
    end subroutine hello
end module liblegacy

program main
    use liblegacy
    implicit none
    call hello
end program main

And now, we are trying to call hello from another main program.

! main.f90
program mycode
    use liblegacy
    implicit none
    print *,'Hello from mycode'
    call hello
end program mycode

If you try to compile it, it will fail

> gfortran-8.3.0 -c legacy.f90
> gfortran-8.3.0 -c main.f90
> gfortran-8.3.0 -o main legacy.o main.o
duplicate symbol '_main' in:
    legacy.o
    main.o
ld: 1 duplicate symbol for architecture x86_64
collect2: error: ld returned 1 exit status

The reason here is, that we have two _main definitions. One in legacy.f90, and another one in main.f90. We can fix that using objcopy. We can weaken _main inside legacy.o.

> gfortran-8.3.0 -c legacy.f90
> objcopy -W _main legacy.o       # Force symbol _main to be marked as a weak
> gfortran-8.3.0 -c main.f90
> gfortran-8.3.0 -o main legacy.o main.o
> ./main
 Hello from mycode
 Hello world!

And voilà!