I'm trying out the examples in the xmlrpc-c documentation:
#include <stdio.h>
#include <xmlrpc.h>
#include <xmlrpc_server.h>
//#include <xmlrpc_server_abyss.h>
#include <xmlrpc_abyss.h>
#include <xmlrpc-c/base.h>
#include <xmlrpc-c/util.h>
static xmlrpc_value *
sample_add(xmlrpc_env * const envP,
xmlrpc_value * const paramArrayP,
void * const serverContext) {
xmlrpc_int32 x, y, z;
/* Parse our argument array. */
xmlrpc_decompose_value(envP, paramArrayP, "(ii)", &x, &y);
if (envP->fault_occurred)
return NULL;
/* Add our two numbers. */
z = x + y;
/* Return our result. */
return xmlrpc_build_value(envP, "i", z);
}
int
main (int const argc,
const char ** const argv) {
xmlrpc_server_abyss_parms serverparm;
xmlrpc_registry * registryP;
xmlrpc_env env;
xmlrpc_env_init(&env);
registryP = xmlrpc_registry_new(&env);
xmlrpc_registry_add_method(
&env, registryP, NULL, "sample.add", &sample_add, NULL);
serverparm.config_file_name = argv[1];
serverparm.registryP = registryP;
printf("Starting XML-RPC server...\n");
xmlrpc_server_abyss(&env, &serverparm, XMLRPC_APSIZE(registryP));
return 0;
}
I try to compile using gcc:
gcc source.c
nohting fancy and I get:
/tmp/ccfGuc6A.o: In function sample_add':
source.c:(.text+0x38): undefined reference toxmlrpc_decompose_value'
source.c:(.text+0x6d): undefined reference to xmlrpc_build_value'
/tmp/ccfGuc6A.o: In functionmain':
source.c:(.text+0x96): undefined reference to xmlrpc_env_init'
source.c:(.text+0xa5): undefined reference toxmlrpc_registry_new'
source.c:(.text+0xd8): undefined reference to xmlrpc_registry_add_method'
source.c:(.text+0x117): undefined reference toxmlrpc_server_abyss'
collect2: error: ld returned 1 exit status
these functions exist in the:
/usr/include/xmlrpc-c/base.h
whihc I have referenced:
include
I think I'm not passing the right options to link, I don't know how it's done though.
thanks
You definitely don't pass the correct argument for the linker. Just including a header file doesn't actually make the linker link with the library, you need to use the -l (lower-case L) option to tell the linker which libraries you need to link with, like
gcc source.c -lxmlrpc
I believe that xml-rpc-c comes with a helper program, intended to help you get the linking right. Its documented here
http://xmlrpc-c.sourceforge.net/doc/xmlrpc-c-config.html
Related
I'm writing an application using libao for audio output. The portion
of my program that calls into libao lives in a shared object:
// playao.c
// compile with: gcc -shared -o libplayao.so playao.c -lao -lm
#include <ao/ao.h>
#include <stdio.h>
#include <math.h>
void playao(void) {
int i;
unsigned char samps[8000];
ao_initialize();
ao_sample_format sf;
sf.bits = 8;
sf.rate = 8000;
sf.channels = 1;
sf.byte_format = AO_FMT_NATIVE;
sf.matrix = "M";
ao_device *device = ao_open_live(ao_default_driver_id(), &sf, NULL);
if(!device) {
puts("ao_open_live error");
ao_shutdown();
return;
}
for(i = 0; i < 8000; ++i) {
float time = (float)i / 8000;
float freq = 440;
float angle = time * freq * M_PI * 2;
float value = sinf(angle);
samps[i] = (unsigned char)(value * 127 + 127);
}
if(!ao_play(device, (char *)samps, 8000)) {
puts("ao_play error");
}
ao_close(device);
ao_shutdown();
}
If I link against this shared object in a program, it works fine:
// directlink.c
// compile with: gcc -o directlink directlink.c libplayao.so -Wl,-rpath,'$ORIGIN'
void playao(void);
int main(int argc, char **argv) {
playao();
return 0;
}
However, if I use dlopen/dlsym to invoke it, there are no errors, but the
program does not cause any sound to be emitted:
// usedl.c
// compile with: gcc -o usedl usedl.c -ldl
#include <dlfcn.h>
#include <stdio.h>
int main(int argc, char **argv) {
void *handle = dlopen("./libplayao.so", RTLD_LAZY);
if(!handle) {
puts("dlopen failed");
return 1;
}
void *playao = dlsym(handle, "playao");
if(!playao) {
puts("dlsym failed");
dlclose(handle);
return 1;
}
((void (*)(void))playao)();
dlclose(handle);
return 0;
}
However, running usedl with LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libao.so.4
does work. So there's something about libao that wants to be loaded when the
program starts up, and doesn't like being loaded any later.
Why is this? Is there any way to work around this, so that libao works
correctly even if loaded later in the program's execution?
I'm running Debian 10 "buster" if it matters.
I asked about this on the #xiph channel on Freenode and xiphmont suggested turning turning on verbose mode. Once I did that, the failing case started getting the message:
ERROR: Failed to load plugin /usr/lib/x86_64-linux-gnu/ao/plugins-4/libalsa.so => dlopen() failed
So libao itself is trying to dlopen something, and it's failing. It's not showing me any more details, so I ran the program under GDB and set a breakpoint on dlopen. After hitting the dlopen breakpoint for libalsa and running finish, I tried finding what the error was by using print (const char *)dlerror(). And with this, I get a more detailed error:
/usr/lib/x86_64-linux-gnu/ao/plugins-4/libalsa.so: undefined symbol: ao_is_big_endian
So ao's libalsa plugin is trying to reference symbols back in libao, but it's not finding them. Why could this be? Referencing the dlopen documentation, I see:
Zero or more of the following values may also be ORed in flags:
RTLD_GLOBAL: The symbols defined by this shared object will be made available for symbol resolution of subsequently loaded shared objects.
RTLD_LOCAL: This is the converse of RTLD_GLOBAL, and the default if neither flag is specified. Symbols defined in this shared object are not made available to resolve references in subsequently loaded shared objects.
Because my dlopen call only used RTLD_LAZY and didn't include RTLD_GLOBAL or RTLD_LOCAL, it defaulted to RTLD_LOCAL, which does not expose the symbols in the shared object (like ao_is_big_endian) to subsequently loaded shared objects (like libalsa.so).
So, I tried changing the code from:
void *handle = dlopen("./libplayao.so", RTLD_LAZY);
To:
void *handle = dlopen("./libplayao.so", RTLD_LAZY | RTLD_GLOBAL);
And lo and behold, it works!
I am trying to build a web crawler and need to parse URIs.
I have tried to compile some simple uriparser code which I copied and pasted from https://uriparser.github.io/doc/api/latest/
#include <uriparser/Uri.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
UriUriA uri;
const char * const uriString = "file:///home/user/song.mp3";
const char * errorPos;
if (uriParseSingleUriA(&uri, uriString, &errorPos) != URI_SUCCESS) {
/* Failure (no need to call uriFreeUriMembersA) */
return 1;
}
/* Success */
uriFreeUriMembersA(&uri);
}
The code doesn't compile and gives the following errors:
/tmp/ccWkKj10.o: In function `main':
uri.c:(.text+0x51): undefined reference to `uriParseSingleUriA'
uri.c:(.text+0x6b): undefined reference to `uriFreeUriMembersA'
collect2: error: ld returned 1 exit status
I have the latest version of liburiparser-dev installed (0.9.3-2).
Any idea what I am doing wrong?
EDIT
Adding flag -luriparser solved the problem.
This question already has answers here:
Cuda C - Linker error - undefined reference
(2 answers)
Closed 7 years ago.
I'm new to CUDA programming hence running into issues with compiling/ linking files. I'm trying to compile .c and .cu files.
Here are the files:
p3.c:
#include <stdlib.h>
#include <stdio.h>
extern void load_scheduler(int k, int j);
int blocks, threads;
int main(int argc, char* argv[])
{
if (argc > 1)
{
blocks = atoi(argv[1]);
threads = atoi(argv[2]);
}
else
exit(1);
load_scheduler(blocks, threads);
}
And scheduler.cu file:
#include <stdlib.h>
#include <stdio.h>
__global__ void sched_func()
{
int j = 6*5*threadIdx.x;
printf("%d\n",j);
}
void load_scheduler(int b, int n)
{
sched_func<<< b,n >>>();
}
I compile these two files using nvcc -c scheduler.cu p3.c and it seems fine
However, when I try to link these two files using nvcc -o cuda_proj scheduler.o p3.o, I get an error:
p3.o: In function `main':
p3.c:(.text+0x58): undefined reference to `load_scheduler'
collect2: ld returned 1 exit status
I may not be using the right steps to get this working, so if there's any other way I should try out, suggestions are welcome. I am also new to making Makefiles so want to stick to using nvcc commands on terminal.
Just added : extern "c" before load_scheduler definition. NVCC could not recognize the function definition as it belonged to .cu file, therefore the error.
extern "C"
void load_scheduler(int b, int n)
{
sched_func<<< b,n >>>();
}
I created a program in C and I tried to compile it. When I use my gcc 4.8.1 compiler in Widows everything worked and my program too.
I compiled with the following arguments:
gcc -std=c99 -O2 -DCONTEST -s -static -lm children.c
But in linux I getting the following error:
/usr/lib/gcc/i486-linux-gnu/4.7/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
Why is that? My programm is working and I can't understand why I getting compiling errors in linux.
My code is:
/*---------------------*/
/* included files */
/*---------------------*/
#include <stdio.h>
#include <stdlib.h>
/*---------------------*/
/* defined constants */
/* for restriction */
/*---------------------*/
#define MIN 1
#define MAX 1000000
#define IOERROR 5 // 'Input/Output Error'
/*---------------------*/
/* function prototypes */
/*---------------------*/
int main();
FILE *read_input(const char *filename_r);
int count_children(FILE *input);
int pass_heights(FILE *input, int *children, int size);
int check_tall(const int *children, int size);
void write_output(const int total,const char *filename_w);
/*---------------------*/
/* start of program */
/*---------------------*/
int main() {
const char *filename_r = "xxx.in";
const char *filename_w = "xxx.out";
FILE *input = read_input(filename_r);
int size = count_children(input);
int *children = malloc(size * sizeof *children);
if (children==NULL)
exit(1); //General application error
pass_heights(input, children, size);
fclose(input);
int total = check_tall(children, size);
free(children);
write_output(total,filename_w);
return 0;
}
FILE *read_input(const char *filename_r) {
FILE *input = fopen(filename_r, "r");
if(input == NULL)
exit(IOERROR);
return input;
}
int count_children(FILE *input) {
int count = 0;
fscanf(input, "%d",&count);
if(count > MAX || count < MIN)
exit(1); //General application error
return count;
}
int pass_heights(FILE *input, int *children, int size) {
for(int i = 0; i < size; i++)
fscanf(input, "%d",&children[i]);
return *children;
}
int check_tall(const int *children, int size) {
int total = 0;
int tmp_max = 0;
for(int i = size - 1; i >= 0; i--)
{
if(children[i] > tmp_max) {
tmp_max = children[i];
total++;
}
}
return total;
}
void write_output(const int total,const char *filename_w) {
FILE *output = fopen(filename_w, "w");
if(output == NULL)
exit(IOERROR);
fprintf(output, "%d\n", total);
fclose(output);
}
You used -static option, which modifies the way executable is linked.
I was unable to reproduce your exact error message, but on my Linux it says that it is unable to link with -lc in static mode, and under my OSX it says that it is unable to locate -lcrt0.o. For me in both case, this means that the system is unable to locate the static stub.
If you remove -static it should work. If not, your problem is very strange.
The error you show indicates the linker is not finding the main() function in your code. As it is evident that you have included it in the source file, it is also evident you are not compiling with that command line (or you are compiling in other directory where you have a non-main() source called children.c, perhaps the build system makes a touch children.c if it doesn't find the source, and then compiles it --on that case it will not have a main() routine). Check that the files are properly created and where, as I think you aren't compiling that file anyway.
Try to use simple options before you go to more complicated ones. Try something like:
gcc -std=c99 -o children children.c
before trying to experiment with optimization or static linking anyway. Also, dynamic linking is normally better than static, so you'll get smaller executables (8Kb vs. 800Kb, and multiple copies of libc loaded per executable). Also, you don't need to include -lm as you aren't using any of the <math.h> functions (having it doesn't hurt anyway).
I have compiled your source with the following command line without any problem, but I do have support for statically linked executables and perhaps you don't (the command line I have put above would work in any linux, I suppose)
$ make CC='gcc' CFLAGS='-std=c99 -O2 -DCONTEST' LDFLAGS='-s -static -lm' children
gcc -std=c99 -O2 -DCONTEST -s -static -lm children.c -o children
children.c: In function ‘pass_heights’:
children.c:81:11: warning: ignoring return value of ‘fscanf’, declared with attribute warn_unused_result [-Wunused-result]
children.c: In function ‘count_children’:
children.c:69:11: warning: ignoring return value of ‘fscanf’, declared with attribute warn_unused_result [-Wunused-result]
Here is some code from Ben Straub's (link blog) that I am basing this on:
static int do_clone(const char *url, const char *path)
{
git_repository *repo = NULL;
int ret = git_clone(&repo, url, path, NULL);
git_repository_free(repo);
return ret;
}
And here is my code:
#include <git2.h>
int main(void) {
git_repository *out = NULL;
git_clone(&out, "https://github.com/lehitoskin/racketball", "/home/maxwell", NULL);
return 0;
}
I am very inexperienced with C, so I apologize for having such elementary problems. Anyway, here is the error my compiler gives me:
maxwell#max-pc ~ $ gcc -I libgit2/include gitfun.c
/tmp/ccB64nPh.o: In function `main':
gitfun.c:(.text+0x31): undefined reference to `git_clone'
collect2: error: ld returned 1 exit status
Why can't I call git_clone this way?
It looks like you didn't link to the library. Add -lgit2 if libgit2 is the lib name.
gcc -I libgit2/include gitfun.c -L<path to lib> -l<libname minus the "lib" part>
IOW, you compile fine but when the linker goes looking for git_clone it can't find it because you haven't specified the library that it is in.