From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9289 invoked by alias); 20 Mar 2008 09:54:40 -0000 Received: (qmail 9275 invoked by uid 22791); 20 Mar 2008 09:54:39 -0000 X-Spam-Check-By: sourceware.org Received: from mgw1.diku.dk (HELO mgw1.diku.dk) (130.225.96.91) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 20 Mar 2008 09:54:20 +0000 Received: from localhost (localhost [127.0.0.1]) by mgw1.diku.dk (Postfix) with ESMTP id E5AEB770026 for ; Thu, 20 Mar 2008 10:54:16 +0100 (CET) Received: from mgw1.diku.dk ([127.0.0.1]) by localhost (mgw1.diku.dk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ybdCQRtHeTt2 for ; Thu, 20 Mar 2008 10:54:07 +0100 (CET) Received: from nhugin.diku.dk (nhugin.diku.dk [130.225.96.140]) by mgw1.diku.dk (Postfix) with ESMTP id B74F9770024 for ; Thu, 20 Mar 2008 10:54:07 +0100 (CET) Received: from tyr.diku.dk (tyr.diku.dk [130.225.96.226]) by nhugin.diku.dk (Postfix) with ESMTP id 8D8026DF823 for ; Thu, 20 Mar 2008 10:53:11 +0100 (CET) Received: by tyr.diku.dk (Postfix, from userid 1018) id 869531DC541; Thu, 20 Mar 2008 10:54:07 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by tyr.diku.dk (Postfix) with ESMTP id 841D71DC471 for ; Thu, 20 Mar 2008 10:54:07 +0100 (CET) Date: Thu, 20 Mar 2008 09:54:00 -0000 From: Klaus Grue To: gcc-help@gcc.gnu.org Subject: Dynamic compilation using gcc Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-IsSubscribed: yes Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2008-03/txt/msg00193.txt.bz2 Hi gcc-help, I have a three questions about dynamic compilation using gcc which I post to gcc-help since I have been unable to find much on the issue using FAQs and Google. I hope someone can provide answers or pointers to information. Background: I need a function void *source2dl(const char *source,int flag); which, given a C source text, compiles the source into a dynamic library and returns a handle to that library. The signature of source2dl() above is identical to that of dlopen(), but source2dl() takes a C source as input where dlopen() takes the pathname of a shared object. I include a working but in some respects inconvenient implementation of source2dl() below. My questions come after the implementation of source2dl(). --------------------------------------------------------------------- #include #include #include #include #include #include #include //Die with last word from perror void pdie(const char *msg){perror(msg);exit(0);} //Die with last word from dlerror void dldie(const char *msg){printf("%s: %s\n",msg,dlerror());exit(0);} //Convert source text to dynamic library void *source2dl(const char *source,int flag){ int fd[2];pid_t pid;int status;void *dl; //Create pipe for piping source to gcc if(pipe(fd)<0) pdie("pipe()"); //Fork a gcc, pipe source to it, wait for gcc to exit pid=fork(); if(pid<0) pdie("fork()"); if(pid==0){ // Child process: close write end of pipe close(fd[1]); // Send pipe input to stdin close(STDIN_FILENO); dup2(fd[0],STDIN_FILENO); // Invoke gcc with the following arguments: // -x c Tell gcc that we provide C source // -pipe Use pipes between gcc stages // -fPIC -shared Make shared object // -Wl,-soname,dl.so Pass suitable options to linker // -o dl.so Write shared object to dl.so execl("/usr/bin/gcc","gcc","-x","c","-pipe","-","-fPIC","-shared", "-Wl,-soname,dl.so","-o","dl.so",(char *)NULL); // Complain if execl() returns pdie("execl()");} //Parent process: close read end of pipe close(fd[0]); //Pipe source to gcc write(fd[1],source,strlen(source)); close(fd[1]); //Wait for gcc to exit if(wait(&status)<0) pdie("wait()"); //Load output from gcc and return it dl=dlopen("./dl.so",flag); if(!dl) dldie("dlopen()"); return dl;} //Main program for testing source2dl() int main(int argc,char *argv[]){ //Set prog to //#include //void fct(){printf("Hello world\n");} char *prog="#include \nvoid fct(){printf(\"Hello world\\n\");}\n"; //Convert prog to dl and extract fct void (*fct)()=dlsym(source2dl(prog,RTLD_NOW),"fct"); if(!fct) dldie("dlsym()"); //Invoke fct (*fct)(); return 0;} --------------------------------------------------------------------- The program above prints "Hello world" to stdout as intended. However, here are my questions: Question 1. The dlopen(), dlclose(), dlsym(), and dlerror() functions from libdl provide a library interface to the dynamic loader. Does there exist a similar library interface to gcc so that one can avoid the pipe-fork-execve-wait overhead of running gcc in a separate process? Question 2. The implementation of source2dl() above uses a temporary file named dl.so for the shared object produced by gcc and read by dlopen. It would be convenient if communication from gcc to dlopen could go via a pipe. Does anyone know a way to tell gcc to write the shared object to stdout? Question 3. Following up on Question 2, does anyone know a way to tell glopen to read the shared object from stdin? I hope someone listening at gcc-help can help on these questions or give pointers to information or give suggestions for alternative ways of doing dynamic compilation. Cheers, Klaus