I've been exploring emscripten by trying to compile some basic wasm example that uses 'sys/shm.h'
Here's the code I'm trying to compile:
#include <stdio.h>
#include <sys/shm.h>
int main(int argc, char *argv[]) {
key_t key = ftok("shmfile",65);
int shmid = shmget(key,1024,0666|IPC_CREAT);
char *str = (char*) shmat(shmid,(void*)0,0);
sprintf(str, "balhhh");
printf("Data in memory: %s\n",str);
shmdt(str);
return 0;
}
Here is my compilation output:
➜ wasm emcc --version
emcc (Emscripten gcc/clang-like replacement) 1.39.8 (commit 1458145cf4f3db0fb548343e6acab267eef8e4ef)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
➜ wasm emcc -o shared.html shared.c -s WASM=1 -s USE_PTHREADS=1
error: undefined symbol: ftok
warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
error: undefined symbol: shmat
error: undefined symbol: shmdt
error: undefined symbol: shmget
Error: Aborting compilation due to previous errors
shared:ERROR: '/home/wave/Downloads/emsdk/node/12.9.1_64bit/bin/node /home/wave/Downloads/emsdk/upstream/emscripten/src/compiler.js /tmp/tmpiWE3Ei.txt' failed (1)
➜ wasm emcc -o shared.html shared.c -s WASM=1 -s USE_PTHREADS=1 -s LLD_REPORT_UNDEFINED
wasm-ld: error: /tmp/emscripten_temp_bNjvle/shared_0.o: undefined symbol: ftok
wasm-ld: error: /tmp/emscripten_temp_bNjvle/shared_0.o: undefined symbol: shmget
wasm-ld: error: /tmp/emscripten_temp_bNjvle/shared_0.o: undefined symbol: shmat
wasm-ld: error: /tmp/emscripten_temp_bNjvle/shared_0.o: undefined symbol: shmdt
wasm-ld: error: /home/wave/.emscripten_cache/wasm-obj/libc-mt.a(emscripten_pthread.c.o): undefined symbol: initPthreadsJS
shared:ERROR: '/home/wave/Downloads/emsdk/upstream/bin/wasm-ld -o /tmp/emscripten_temp_bNjvle/shared.wasm --lto-O0 /tmp/emscripten_temp_bNjvle/shared_0.o -L/home/wave/Downloads/emsdk/upstream/emscripten/system/local/lib -L/home/wave/Downloads/emsdk/upstream/emscripten/system/lib -L/home/wave/.emscripten_cache/wasm-obj /home/wave/.emscripten_cache/wasm-obj/libc-mt.a /home/wave/.emscripten_cache/wasm-obj/libcompiler_rt.a /home/wave/.emscripten_cache/wasm-obj/libc-wasm.a /home/wave/.emscripten_cache/wasm-obj/libdlmalloc-mt.a /home/wave/.emscripten_cache/wasm-obj/libpthread-mt.a /home/wave/.emscripten_cache/wasm-obj/libc_rt_wasm.a /home/wave/.emscripten_cache/wasm-obj/libsockets-mt.a --allow-undefined-file=/tmp/tmp5_bZ9l.undefined --import-memory --import-table --shared-memory -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --strip-debug --export __wasm_call_ctors --export __data_end --export main --export __errno_location --export emscripten_get_global_libc --export __pthread_tsd_run_dtors --export __emscripten_pthread_data_constructor -z stack-size=5242880 --initial-memory=16777216 --no-entry --max-memory=16777216 --global-base=1024' failed (1)
I guess there is shared memory support in emscripten, but I just can't get wasm-ld to link it correctly.
Can anyone help?
Thanks,
Gal
Emscripten does not support SysV shared memory (the functions in sys/shm.h).
Related
Could someone help me understand, why after generating the object file with using ASan flag (compiler flag), when linking the object file still needs the same flag? (linker flag)
For example
clang -fsanitize=address -c test.c
clang -fsanitize=address test.o -o test.exe
When you compile your program with Address Sanitizer, it instruments every memory access and prefixes it with a check and includes the function calls to report memory access errors.
For e.g.
Sample program which leaks memory and try to access array beyond its size:
#include <stdio.h>
#include <stdlib.h>
void fun (void) {
void *p = malloc(1);
char a[] = "abc";
printf ("%c\n", a[4]);
}
int main (void) {
fun();
return 0;
}
Compiling:
# gcc -fsanitize=address -g -c test.c
# ls
test.c test.o
Linking without -fsanitize=address:
# gcc -g test.o -o test.exe
test.o: In function `fun':
/root/mywork/asan/sample7/test.c:4: undefined reference to `__asan_option_detect_stack_use_after_return'
/root/mywork/asan/sample7/test.c:4: undefined reference to `__asan_stack_malloc_1'
/root/mywork/asan/sample7/test.c:6: undefined reference to `__asan_report_store4'
/root/mywork/asan/sample7/test.c:8: undefined reference to `__asan_report_load1'
test.o: In function `_GLOBAL__sub_D_00099_0_fun':
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_unregister_globals'
test.o: In function `_GLOBAL__sub_I_00099_1_fun':
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_init'
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_version_mismatch_check_v8'
/root/mywork/asan/sample7/test.c:14: undefined reference to `__asan_register_globals'
collect2: error: ld returned 1 exit status
The code of test.o is instrumented by Address Sanitizer. The Address Sanitizer runtime library replaces malloc() call with its own malloc() function call (which allocate requested amount of memory with redzone around it) and provides error reporting function like __asan_report_load1(), __asan_report_store4() etc. In order to resolve these functions, the -fsanitize=address flag is required at the time of linking to tell linker to check the ASan runtime library to resolve the references.
Linking with -fsanitize=address:
# gcc -fsanitize=address -g test.o -o test.exe
# ls
test.c test.exe test.o
If you don't want to use -fsanitize=address flag with linker, you can provide the Address Sanitizer library to the linker which it can use to resolve the references:
# ls
test.c test.o
# gcc -lasan -g test.o -o test.exe
# ls
test.c test.exe test.o
I am on Debian 10 and I want to develop an C application for PostgreSQL. This is why I installed a packages postgresql and libpq-dev. Later clearly installed header files inside the system folders:
┌───┐
│ $ │ ziga > ziga--workstation > 001--hello_world
└─┬─┘
└─> find /usr/include/ | grep libpq
/usr/include/postgresql/libpq-fe.h
/usr/include/postgresql/libpq
/usr/include/postgresql/libpq/libpq-fs.h
/usr/include/postgresql/libpq-events.h
/usr/include/postgresql/internal/libpq
/usr/include/postgresql/internal/libpq/pqcomm.h
/usr/include/postgresql/internal/libpq-int.h
But when I compile this simple C program:
#include <stdio.h>
#include <postgresql/libpq-fe.h>
int main(int argc, char * argv[]){
int v = PQlibVersion();
printf("Version of libpq: %d\n", v);
return 0;
}
compiler says:
gcc -std=c17 -Wall -Wpedantic -g -gdwarf-2 -o main.elf main.c
/usr/bin/ld: /tmp/ccVzig6T.o: in function `main':
/home/ziga/Dropbox/workspace/racunalnistvo/projects--pistam/2021-03-03--postgressql_c/001--hello_world/main.c:6: undefined reference to `PQlibVersion'
collect2: error: ld returned 1 exit status
make: *** [makefile:59: main.elf] Error 1
I don't understand. Header files are inside /usr/include where they should be found...
Is library not being found or what? It is also installed...
┌───┐
│ $ │ ziga > ziga--workstation > 001--hello_world
└─┬─┘
└─> find /usr/lib | grep libpq
/usr/lib/x86_64-linux-gnu/libpq.a
/usr/lib/x86_64-linux-gnu/libpq.so
/usr/lib/x86_64-linux-gnu/libpq.so.5
/usr/lib/x86_64-linux-gnu/pkgconfig/libpq.pc
/usr/lib/x86_64-linux-gnu/libpq.so.5.11
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqsignal.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-secure-openssl.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/auth.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqcomm.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-fsstubs.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqformat.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/ifaddr.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-secure.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/pqmq.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/crypt.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/be-secure-common.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/hba.bc
/usr/lib/postgresql/11/lib/bitcode/postgres/libpq/auth-scram.bc
/usr/lib/postgresql/11/lib/libpqwalreceiver.so
Can anyone tell me how to best solve this?
As the log says, The linker is unable to find any reference to PQlibVersion. Since the linker is running, it clearly is not a problem of compiling but linking.
/usr/bin/ld: /tmp/ccVzig6T.o: in function `main':
/home/ziga/Dropbox/workspace/racunalnistvo/projects--pistam/2021-03-03--postgressql_c/001--hello_world/main.c:6: undefined reference to `PQlibVersion'
collect2: error: ld returned 1 exit status
I think you should add linker options to link against the postgress library. Add -lpq option to you compiler arguments. For a more complete explanation, please read Building libpq Programs.
I'm trying to write my own shared library to link to an executable, but can't get the .so to link.
I'm using a very basic example to try and get it working. The shared library (test_lib.c):
#include "test_lib.h" //stdlib includes and function prototype
char *hello(void) {
char *c = malloc(100);
memcpy(c, "hello\n", 7);
return c;
}
The executable (test.c):
#include "test_lib.h"
int main() {
printf("%s", hello());
return 0;
}
Following all the guides I can find, I compile the .so with gcc -I . -fPIC -shared -o test_lib.so test_lib.c, and then the executable (in the same directory) with gcc -I . -L . test.c -ltest_lib
This gives the error:
/usr/bin/ld: cannot find -ltest_lib
collect2: error: ld returned 1 exit status
As I understand including the path through the -L flag should tell gcc where to find the .so, but this isn't working. What am I missing here?
When linking a library, the library usually has to be named libxxx.a|so for the linker to find it.
Compiling the library:
gcc -I . -fPIC -shared -o libtest.so test_lib.c
Then you can link with:
gcc -I . -L . test.c -ltest
I'm having a problem linking Intel MKL and libdl using the gold linker on CentOS:
When I run this script:
#!/bin/bash
MKL_INC=$MKL_INSTALL_DIR/include
MKL_LIB=$MKL_INSTALL_DIR/lib
. /opt/rh/devtoolset-6/enable
cat > t.c << end_mkltest
#include <dlfcn.h>
#include "mkl_service.h"
int main() {
dlerror(); /* use libdl */
mkl_set_num_threads(1); /* use mkl */
}
end_mkltest
gcc -I$MKL_INC -c t.c -o t.o
gcc -L$MKL_LIB -fuse-ld=gold t.o -lmkl_rt -ldl
I get:
libmkl_rt.so: error: undefined reference to 'calloc'
libmkl_rt.so: error: undefined reference to 'realloc'
libmkl_rt.so: error: undefined reference to 'malloc'
libmkl_rt.so: error: undefined reference to 'free'
We're using:
CentOS 7.3
devtoolset-6
mkl-2017.2.174.tar.bz2
Any ideas?
This should work. Can you post the linker command shown by this command?
gcc -v -L$MKL_LIB -fuse-ld=gold t.o -lmkl_rt -ldl
(Sorry, can't post this as a comment due to lack of reputation.)
I am using Cygwin environment with Lua Interpreter package included while cygwin installation.
So I am able to compile and run sample lua progs.
But when i try to execute a sample c file which has lua calls , i am always getting this following error.
$ cc -o ../samples/ctest -Wall ../samples/ctest.c
/tmp/ccOYgLj4.o:ctest.c:(.text+0x2b): undefined reference to `_luaL_newstate'
/tmp/ccOYgLj4.o:ctest.c:(.text+0x3d): undefined reference to `_luaL_openlibs'
/tmp/ccOYgLj4.o:ctest.c:(.text+0x59): undefined reference to `_luaL_loadfile'
/tmp/ccOYgLj4.o:ctest.c:(.text+0x82): undefined reference to `_lua_pcall'
/tmp/ccOYgLj4.o:ctest.c:(.text+0xb8): undefined reference to `_lua_getfield'
/tmp/ccOYgLj4.o:ctest.c:(.text+0xd5): undefined reference to `_lua_call'
/tmp/ccOYgLj4.o:ctest.c:(.text+0xf0): undefined reference to `_lua_close'
collect2: ld returned 1 exit status
My sample ctest.c file contents:
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
/* lua interpreter */
lua_State* l;
int main () {
int dofile;
/* initialize lua */
l = lua_open();
/* load lua libraries */
luaL_openlibs(l);
/* run the hello.lua script */
dofile = luaL_dofile(l, "hello.lua");
if (dofile == 0) {
/* call foo */
lua_getglobal(l,"foo");
lua_call(l,0,0);
}
else {
printf("Error, unable to run hello.lua\n");
}
/* cleanup Lua */
lua_close(l);
return 0;
}
hello.lua file contents:
print("from c hurray")
on searching the net everywhere they say some linker error and have to include -llua51. So i tried the following .
$ cc -o ../samples/ctest -Wall -llua5.1 ../samples/ctest.c
/tmp/cc3v5Nim.o:ctest.c:(.text+0x2b): undefined reference to `_luaL_newstate'
/tmp/cc3v5Nim.o:ctest.c:(.text+0x3d): undefined reference to `_luaL_openlibs'
/tmp/cc3v5Nim.o:ctest.c:(.text+0x59): undefined reference to `_luaL_loadfile'
/tmp/cc3v5Nim.o:ctest.c:(.text+0x82): undefined reference to `_lua_pcall'
/tmp/cc3v5Nim.o:ctest.c:(.text+0xb8): undefined reference to `_lua_getfield'
/tmp/cc3v5Nim.o:ctest.c:(.text+0xd5): undefined reference to `_lua_call'
/tmp/cc3v5Nim.o:ctest.c:(.text+0xf0): undefined reference to `_lua_close'
collect2: ld returned 1 exit status
Vedhashree#Vedhashree-PC /cygdrive/c/cygwin/bin
$ ls /usr/lib/liblua*.a
/usr/lib/liblua.a /usr/lib/liblua5.1.a
/usr/lib/liblua.dll.a /usr/lib/liblua5.1.dll.a
Can you help me fix this issue and make my first embedded lua c program work?
Update:
$ cc -o ctesing -Wall ctesting.c -llua5.1
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find
-llua5.1
collect2: ld returned 1 exit status
-----------------------------------------------------------------
cc -o ../samples/ctest -Wall ../samples/ctest.c -llua
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find
-llua51
collect2: ld returned 1 exit status
-----------------------------------------------------------------
cc -o ../samples/ctest -Wall ../samples/ctest.c -llua51
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot find
-llua
collect2: ld returned 1 exit status
-----------------------------------------------------------------
Still I get only these errors :(
Place -llua5.1 after ../samples/ctest.c. Objects should be linked in reverse order of dependency.
cc -o ../samples/ctest -Wall ../samples/ctest.c -llua5.1
UPDATE: Your update describes a different problem. In this case the linker cannot find a liblua5.1.a file in its search path. Make sure that you have such a library on your system and try adding its path using the -L option.