I’m trying to create ./configure + make set for building C codes in following structure by using autotools. drive.c uses function in mylib.c
[mylib]
+mylib.c
+mylib.h
[src]
+drive.c
More details are here.
[mylib.c]
#include <stdio.h>
#include "mylib.h"
int main(){
mylib();
return 0;
}
void
mylib(void)
{
printf ("Hello world! I AM mylib \n");
}
[mylib.h]
void mylib(void);
[drive.c]
#include <mylib.h>
int
main (int argc, char **argv)
{
mylib();
return 0;
}
Actually I’ve given main() both mylib.c and drive.c.
If I make them on CentOS process is noremally finished however If I make them on MINGW an error message multiple definition ofmain'` is shown
How can I make them on MINGW even if they have multiply have main()?
And those followings are config files for autotools.
[confiugre.ac]
AC_PREREQ([2.69])
AC_INIT([libmylib], [1], [admin#localhost])
AC_CONFIG_SRCDIR([mylib/mylib.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_PROG_CC
AC_CONFIG_FILES([mylib/Makefile
src/Makefile
Makefile])
AC_OUTPUT
[Makefile.am]
SUBDIRS = mylib src
ACLOCAL_AMFLAGS = -I m4
[Makefile.am#src]
bin_PROGRAMS = drive
drive_SOURCES = drive.c
LDADD = ../mylib/libmylib.la
AM_CPPFLAGS = -I../mylib
[Makefile.am#mylib]
lib_LTLIBRARIES = libmylib.la
libmylib_la_SOURCES = mylib.c
include_HEADERS = mylib.h
You are confusing things, the idea of having multiple main() is fundamentally wrong. Libraries never ever contain a main() function.
(With the exception of Windows DLLs that contain a DllMain, but that means something different.)
If you want to provide a test case for your library, you make the test case as a separate project which includes the library. The test code should not be inside the library itself, neither should main().
Also, I very much doubt you are able to build a program with several function definitions that have the same name, be it main() or something else. If you believe you have managed this, I would either suspect that you haven't linked the files correctly, or that the linker is crap.
Related
I have 2 c files (& their header files). I have included the function "put" in the corresponding header, but I still have the following errors, when I input "gcc -o main main.c" in the terminal.
main.c:(.text+0x389): undefined reference to `put' collect2: error: ld
returned 1 exit status
may I know the reason? How should I modify my code?
I tried to change the linking order in makefile but failed. Any advice is appreciated, thanks!
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(Demo)
set(CMAKE_CXX_STANDARD 14)
include_directories(.)
add_executable(Demo
main.c main.h KeyValueStore.c KeyValueStore.h )
main.c
#include "main.h"
...
int main() {
...
if (strcmp("PUT", tokens[0]) == 0) {
put(tokens[1], tokens[2]);
...
}
main.h
...
#include "KeyValueStore.h"
...
KeyValueStore.c
#include "KeyValueStore.h"
#define BUFSIZE 1024
typedef struct KeyValueStore {
char key[BUFSIZE];
char value[BUFSIZE];
} KV_Store;
KV_Store kvStore[BUFSIZE];
...
int put(char* key, char* value){
...
}
KeyValueStore.h
...
typedef struct KeyValueStore;
int put(char* key, char* value);
...
Check to see if you have any .o files in that folder and delete them if you do. It's possible the compiler failed at some point while compiling which left *.o files that aren't linked properly
EDIT: I misread the question because for some reason it came up as a c++17 question for me. I'm not sure if what I said still applies to C though I do know it works with C++. Sorry about that to everyone that read my answer before I edited it
Not 100% sure if this is why you are having the error, though you need to put all .c files in the compiler.
So you currently are trying to "gcc -o main main.c" where instead you want to do something more like "gcc -o main main.c keyValueStore.c".
If you do not give the compiler every .c file, it won't have all the definitions and you will get an error similar to what you have.
I also don't really think you need main.h, assuming there isn't any more code in there, it really isn't worth having a whole extra file and instead just putting the #include in main.c.
I am trying to make a C program using libmbus, which I have installed on my raspberry pi. In my /usr/lib directory I have the file libmbus.so and in my /usr/include directory I have the the file ./mbus/mbus.h.
The program looks like this:
#include <stdio.h>
#include <mbus/mbus.h>
int main(void)
{
mbus_handle* MbusHandle;
MbusHandle = mbus_connect_serial("/dev/ttyS1");
return 0;
}
When I try to run "gcc main.cpp -lmbus" I get:
main.cpp:(.text+0xe): undefined reference to `mbus_connect_serial(char const*)'
I tried to run
nm -D /usr/lib/libmbus.so
which among others gives
00009930 T mbus_connect_serial
So it appears that the function mbus_connect_serial is part of libmbus.so.
In the header file the function mbus_connect_serial is defined like this:
mbus_handle * mbus_connect_serial(const char * device);
I can't seem to figure out what is wrong. Can anyone guide me in the right direction?
If you're really trying to create a c program, rename main.cpp to main.c
I want to use the C-coder in Matlab. This translates an m-code to C-code.
I use a simple function that adds 5 numbers.
When the code is generated there are a lot of C- and H-files.
of course you could just pick the code you need and import it in your code, but that's not the point of this exercise, as this will no longer be possible when the matlab-code will get more difficult.
Matlab delivers a main.c file and a .mk file.
/* Include Files */
#include "rt_nonfinite.h"
#include "som.h"
#include "main.h"
#include "som_terminate.h"
#include "som_initialize.h"
//Declare all the functions
int main(int argc, const char * const argv[]){
(void)argc;
(void)argv;
float x1=10;
float x2=20;
float x3=30;
float x4=40;
float x5=50;
float result;
/* Initialize the application.
You do not need to do this more than one time. */
som_initialize();
main_som();
result=som(x1,x2,x3,x4,x5);
printf("%f", result);
som_terminate();
return 0;
}
When I run this on a raspberry-pi with
gcc -o test1 main.c
It gives me undefined references to all the functions...
Any ideas what went wrong?
You have to build it with the generated makefile (the mk file) so it links with the correct Matlab libraries - that's where those functions are defined:
$ make -f test.mk
You also need to compile the other C files along with your main.c. If main.c is in the same directory as the generated code, you should be able to just do:
gcc -o test1 *.c
If the generated code is in another directory, then you can do something like:
gcc -o test1 /path/to/code/*.c -I/path/to/code main.c
I have the following files:
C file with functions:
// funcs.c
#include <stdio.h>
void something() {
printf("something\n");
sayHello();
}
System verilog file:
// hello_world.v
module kuku;
export "DPI-C" function sayHello;
import "DPI-C" function void something();
initial something();
function int sayHello ();
$display("hello world");
sayHello = 1;
endfunction
endmodule
How can I compile it and make this work so when I call something() from SV, it will call the C function, and when I call sayHello() from C, it will call the SV function?
Answering myself:
When SV code is compiled using VCS, it is first translated into C code.
When exporting a function out of SV, it generates a C header file vc_hdrs.h that should be included by the C file.
So a change I made in the C file is to add the line:
#include "vc_hdrs.h"
Then, I just added the C functions file to the VCS compilation command:
> vcs -sverilog hello_world.v funcs.c
It works!
The output I get is:
something
hello world
.
A solution that works with all simulator that follow IEEE Std 1800-2012 is to have #include "svdpi.h" and prefix the extern keyword in front of all methods being exported to C. funcs.c should look like:
#include <stdio.h>
#include "svdpi.h"
extern int sayHello();
void something() {
printf("something\n");
sayHello();
}
Examples from IEEE Std 1800-2012
§ H.10.2 Example 2—Simple packed array application
§ H.10.3 Example 3—Application with complex mix of types
I see you've named SystemVerilog file as .v extension. Not sure if that works or not. But lets say if its hello_world.sv
Your command line should look like this (for Questa Simulator),
qverilog hello_world.sv funcs.c
"qverilog " is to compile and run SystemVerilog files.
That's all. No need to add extra header files
Hi I have provided a nice example under this post
https://stackoverflow.com/a/46441794/5842403
Synopsys VCS
1) You compile the C code using flags and introducing the defines you want to add.
In our case our C code need the define PYTHON_PATH
#GCC in two steps for shared object
gcc -g -D 'PYTHON_PATH="'$PYTHON_DIR'"' -fPIC -Wall -I${VCS_HOME}/include -I/usr/include/python2.6/ -lpython2.6 -c ${PROJECTDIR}/verification/PVE/keycontrol/tb/keycontrol_C_code_wrapper.c
gcc -fPIC -shared -o keycontrol_C_code_wrapper.so keycontrol_C_code_wrapper.o
2) You do the VCS elaboration linking the python lybrary with -LDFLAGS '-lpython2.6'
vcs -timescale=1ps/1ps -ntb_opts uvm -lca -kdb -full64 keycontrol_tb_top -debug_access+all+reverse -LDFLAGS '-lpython2.6'
3) You run the created simulation file. You call simv including -sv_lib keycontrol_C_code_wrapper to import the C shared object.
#RUN C CODE
./simv -gui -ucli +DVE +UVM_NO_RELNOTES -l simv.log +UVM_TESTNAME=keycontrol_basic_test -do ../../verification/PVE/keycontrol/tools/keycontrol_ucli_init.synopsys -sv_lib keycontrol_C_code_wrapper
everybody out there
i write a very simple c code which is following:
#include<stdio.h>
int main()
{
int a,b,s,m,d;
system("clear");
int a =20;
int b =40;
s=sum(a,b);
m=mul(a,b);
d=div(a,b);
printf("\n the sum of given no. = %d\nThe product of given no. = %d\nThe division of given no = %d",s,m,d);
return 0;
}
the name of the file is exp.c
than i write the following code:
#include<stdio.h>
int sum( int x ,int y)
{
int z;
z=x+y;
return z;
}
i saved it as sum.c
than i write the following code :
#include<stdio.h>
int mul( int z ,int u)
{
int v ;
v=z+u;
return v;
}
save it as mul.c
than i write the following code
#include<stdio.h>
int div (int a, int b)
{
int f;
f=a/b;
return f;
}
save it as div .c
now my problem is that i want to use all file as a single project.
i want exp.c use the function defined in mul.c,div.c,sum.c
i want to know how to do this?
how to make library form mul.c,div.c,sum.c?
how to associate these library with exp.c ?
can any body explain me the detail process of making project ?
i 'm using ubuntu as my operating system. please help me
The easiest way is to not make a library, but just compile them all together into a single executable:
$ gcc -o myprogram sum.c mul.c div.c
This has the drawback that you will re-compile all the code all the time, so as the files grow large, the penalty (build time) goes up since even changing just div.c (for example) will force you to re-compile sum.c and mul.c too.
The next step is to compile them separately, and leave the object files around. For this, we can use a Makefile like so:
myprogram: sum.o mul.o div.o
sum.o: sum.c
mul.o: mul.c
div.o: div.c
This will leave the object files around, and when you type make the make tool will compare the timestamps of the object files to those of the C files, and only re-compile that which changed. Note that for the above to work, there must be a physical TAB after each colon.
There are a few steps you need to do for this:
Declare the functions in your main file When you compile your main file (exp.c) the compiler will output an error because he does not know what kind of functions sum, mul etc. are. So you have to declare them via int sum( int x ,int y); in this file. A more general approach (which is clearer) is to write all the functions you have in a file (not all, but those that will be accessed from other files) into a header file and then include the header file.
Compile each file You need to compile each file. This can be done via a simple gcc -c mul.c etc. This will create a mul.o - a machine language file.
Link them Once every file is compiled you need to put them together in one executable. This is done via gcc -o outputname mul.o sum.o ...
Note that steps 2 and 3 can also be combined, I just wanted to explain the steps clearly. This is usually done via a Makefile to speed things up a bit
Firstly, you will need to declare each of your functions in a corresponding header file (you don't have to use header files, but it's the most common way of doing this). For instance, div.h might look like:
#ifndef DIV_H_
#define DIV_H_
int div(int a, int b);
#endif
You will then to #include the header files in source files where the corresponding functions are used.
Then, to compile and link:
gcc -o my_prog exp.c sum.c mul.c div.c
As others have suggested, you make want to read up on Make, as it helps simplify the build process once your project gets more complicated.
You need to declare the functions in the file they are used. The common way to do this is to put the declarations in a header file, lets say funcs.h:
#ifndef FUNCS_H
#define FUNCS_H
int sum( int, int );
int mul( int, int );
int div( int, int );
#endif
Now #include this in your main source file. Then to build the executable:
gcc exp.c sum.c div.c mul.c
To create a library, you need to compile the files separately:
gcc -c sum.c div.c mul.c
and then run ar to build the library:
ar rvs sum.o div.o mul.o mylib.a
And then use it from gcc:
gcc exp.c mylib.a
A good practise to organize the code could be put all the functions prototypes inside a .h file, and the implementations into a related .c file, using include guards to avoid multiple inclusion.
Example module.h file:
#ifndef MODULE_NAME
#define MODULE_NAME
void module_func();
#endif
Example module.c :
#include "module.h"
void module_func(){
//implementation
}
read up on make - this will answer your questions about building/compilation/etc
You should have a .h file that will include your function prototypes. It's not strictly needed (as your functions return int) but you must get in the habit now, because it won't come easy later