SamratV
SamratV

Reputation: 226

GCC compilation problem - fatal error: cannot find 'ld'

When I run the following code I get collect2: fatal error: cannot find 'ld' compilation terminated. as output. My GCC version is gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0. It seems it is unable to locate ld module. I don't know how to proceed ahead.

#define _GNU_SOURCE
#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main(){
    char *stderr = "/home/vs/Desktop/test/output.txt";
    char *args[] = {"/usr/bin/gcc",
                    "-Wall",
                    "-O2",
                    "-std=gnu11",
                    "-fomit-frame-pointer",
                    "/home/vs/Desktop/test/Solution.c",
                    "-o",
                    "/home/vs/Desktop/test/Solution",
                    "-lm",
                    NULL};
    char *env[]  = {"LANG=en_US.UTF-8", "LANGUAGE=en_US:en", "LC_ALL=en_US.UTF-8", NULL};

    int fd;
    if(0 > (fd = open(stderr, O_WRONLY|O_TRUNC))) perror("open");
    if(0 > dup2(fd, 2)) perror("dup");
    if(fd != 2) close(fd);

    int x = execve("/usr/bin/gcc", args, env);
    printf("%d\n", x);
    return 0;
}

Upvotes: 2

Views: 7672

Answers (1)

John Bollinger
John Bollinger

Reputation: 180048

Since the same compilation command works when issued via a shell, but fails when issued programmatically as shown, the problem is very likely with the environment you are supplying to execve(). Note in particular that the environment array provided to that function represents the whole environment for the command, not merely extra entries.

Particularly relevant in that regard is that the provided environment does not include a PATH variable. The exec'd process will therefore need to use a fully-qualifed path to any commands it wants to launch in turn, such as ld. If it does not do so, then just such an error as you report will occur. Adding a PATH to the specified environment should resolve the issue. You could copy that from the program's own environment, or, more easily, insert a default path. For example,

    // ...

    char *env[]  = {
        "PATH=/usr/local/bin:/usr/bin:/bin",  // <--- this
        "LANG=en_US.UTF-8",
        "LANGUAGE=en_US:en",
        "LC_ALL=en_US.UTF-8",
        NULL
    };

    // ...

Upvotes: 5

Related Questions