An extremely simple problem demonstration:
#include <stdio.h>
void myFunc()
{
puts("Greetings, Code 'Mon ...");
}
int main(int argc, char *argv[])
{
puts("zMain 01.\n");
myFunc();
puts("zMain 02.\n");
}
Target main_test2.run emits "file not found" as made via gcc
on Ubuntu 20.04.6 LTS:
...
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401030
...
/main_test/yikes01$ ./main_test2.run
bash: ./main_test2.run: No such file or directory
The same runs, yet ignores main() as the |starting| point on MinGW / Windows 10:
c:\tmp\main_test\yikes01>main_test2.run
Greetings, Code 'Mon ...
c:\tmp\main_test\yikes01>main_test.run
zMain 01.
Greetings, Code 'Mon ...
zMain 02.
Project + makefile is at github, yet here is the later:
cc=gcc -v
opts =
link = ld
ifdef OS
libs = -LC:/Windows/System32 -lkernel32 -lmingw32 -lcrtdll
else
libs = -lc
endif
all: main_test2.run main_test.run Makefile
# First function becomes void main(void) ...
main_test2.run: main_test.c
$(cc) $(opts) -c main_test.c
$(link) main_test.o -o main_test2.run $(libs)
rm -f main_test.o
main_test.run: main_test.c
gcc main_test.c -o main_test.run
clean:
rm -f *.o
rm -f *.run
Any ideas what's going spare, here? How to link in gmon_start?
Note: Swapping around parameters does indeed create some marginally different results - direct compliation at the CLI (main_test.run) always works.
Change link = ld
to link = gcc
, in which case you can also discard libs = -lc
.
The bare linker (ld
) only links what you specify, which does not include program
startup code. When invoked via gcc
(as is usual), gcc
appends
boilerplate to the linker's commandline, including the required language runtime and
startup code.
After that change, you will be able to see the extra libraries and object files added to
the linkage if you inspect the output with gcc -v
.