I've cloned the LuaJIT git repo and built it with:
make STATIC_CC="musl-gcc" BUILDMODE="static"
Then, I compiled a simple Lua "hello world" script into a C header file:
luajit -b test.lua test.h
test.h:
#define luaJIT_BC_test_SIZE 52
static const unsigned char luaJIT_BC_test[] = {
27,76,74,2,10,45,2,0,3,0,2,0,4,54,0,0,0,39,2,1,0,66,0,2,1,75,0,1,0,20,72,101,
108,108,111,32,102,114,111,109,32,76,117,97,33,10,112,114,105,110,116,0
};
After that, I wrote a simple C wrapper by following the official example, test.c:
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "test.h"
int main(void) {
int error;
lua_State *L = lua_open();
luaL_openlibs(L);
error = luaL_loadbuffer(L, (const char *) luaJIT_BC_test, luaJIT_BC_test_SIZE, "test") || lua_pcall(L, 0, 0, 0);
if (error) {
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L);
return 0;
}
But when I try to build it, it crashes with an error:
$ musl-gcc -static -ILuaJIT/src -LLuaJIT/src -o test test.c -lluajit
/usr/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/12.1.0/libgcc_eh.a(unwind-dw2-fde-dip.o): in function `_Unwind_Find_FDE':
(.text+0x1953): undefined reference to `_dl_find_object'
collect2: error: ld returned 1 exit status
It's related to libgcc, so I tried building everything with musl-clang, but still got the same error. Can someone explain what I'm missing here?
Figured it out - I needed to build LuaJIT with TARGET_XCFLAGS=-DLUAJIT_NO_UNWIND like so:
make STATIC_CC="musl-gcc" BUILDMODE="static" TARGET_XCFLAGS=-DLUAJIT_NO_UNWIND
I guess this just disables C++ exceptions support, but I'm not sure what the real implications are. Seems to work fine, for now.
The following code sample is compiled with the subsequent command line input
#include <pthread.h>
#include <stdio.h>
#include <string>
#include <map>
typedef std::map<std::string, std::string> map_t;
void *threadfunc(void *p) {
map_t& m = *(map_t*)p;
m["foo"] = "bar";
return 0;
}
int main() {
map_t m;
pthread_t t;
pthread_create(&t, 0, threadfunc, &m);
printf("foo=%s\n", m["foo"].c_str());
pthread_join(t, 0);
}
Command line input:
g++ thread.cpp -fsanitize=thread -fPIE -pie -lpie -g
It compiles fine, but when the code is run there are runtime errors.
FATAL: ThreadSanitizer can not mmap the shadow memory (something is mapped at 0x56167ae3b000 < 0x7cf000000000)
FATAL: Make sure to compile with -fPIE and to link with -pie.
I am running this with a version of g++ that has fSanitize so I am unsure about where the source of the problem is?
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
GCC is too old for Linux kernel used in your RedHat. Due to the mapped address 0x56167ae3b000 I guess the kernel version is 4.1+ (or backported from the kernel version 4.1+) that maps binaries at 0x550000000000. This mapped address is supported by GCC starting from the version 7.1.1. Please try to add the compiler flag -static-libtsan. If it does not help then you need to upgrade your compiler.
Why am I not able to compile my code to c++ 11 and use the srand48 function?
I have a program where I play around with some matrices.
The problem is that when I compile the code with the -std=c++0x flag.
I want to use some c++11 only functions and this is my approach to do so.
It compiles without any problems if I do not specify the c++ version. Like this:
g++ -O2 -Wall test.cpp -o test -g
Please correct me if I have misunderstood what the mentioned flag does.
I run my code on a Windows 7 64-bit machine and compile through cygwin. I use g++ version 4.5.3 (GCC). Please comment if more information is required.
For some unknown reason (even to myself) then all my code is written in one compilation unit.
If the error is caused by a structural error then you should also feel free to point it out. :)
I receive the following errors:
g++ -std=c++0x -O2 -Wall test.cpp -o test -g
test.cpp: In function ‘void gen_mat(T*, size_t)’:
test.cpp:28:16: error: there are no arguments to ‘srand48’ that depend on a template parameter, so a declaration of ‘srand48’ must be available
test.cpp:28:16: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
test.cpp:33:28: error: there are no arguments to ‘drand48’ that depend on a template parameter, so a declaration of ‘drand48’ must be available
Here is a sub of my code, it generates the errors shown above.
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <limits.h>
#include <math.h>
#define RANGE(S) (S)
// Precision for checking identity.
#define PRECISION 1e-10
using namespace std;
template <typename T>
void gen_mat(T *a, size_t dim)
{
srand48(dim);
for(size_t i = 0; i < dim; ++i)
{
for(size_t j = 0; j < dim; ++j)
{
T z = (drand48() - 0.5)*RANGE(dim);
a[i*dim+j] = (z < 10*PRECISION && z > -10*PRECISION) ? 0.0 : z;
}
}
}
int main(int argc, char *argv[])
{
}
Regards Kim.
This is the solution that solved the problem for me:
First n.m. explained that srand() can not be used when compiling with -std=c++0x.
The correct flag to use is -std=gnu++11 however it require g++ version 4.7+
Therefore, the solution for me was to compile my code with -std=gnu++0x
The compile command = g++ -O2 -Wall test.cpp -o test -g -std=gnu++0x
If you explicitly set -stc=c++03 you will get the same error. This is because drand48 and friends are not actually a part of any C++ standard. gcc includes these functions as an extension, and disables them if standard behaviour is requested.
The default standard mode of g++ is actually -std=gnu++03. You may want to use -std=gnu++11 instead of -std=c++0x, or pass -U__STRICT_ANSI__ to the compiler.
I want to reproduce this Perl code in C, bundling API and CLI in the same C source code file (scriptedmain). This is done in Python with if __name__=="__main__": main() and in gcc/Unix, this looks like:
$ gcc -o scriptedmain scriptedmain.c scriptedmain.h
$ ./scriptedmain
Main: The meaning of life is 42
$ gcc -o test test.c scriptedmain.c scriptedmain.h
$ ./test
Test: The meaning of life is 42
scriptedmain.h
int meaning_of_life();
scriptedmain.c
#include <stdio.h>
int meaning_of_life() {
return 42;
}
int __attribute__((weak)) main() {
printf("Main: The meaning of life is %d\n", meaning_of_life());
return 0;
}
test.c
#include "scriptedmain.h"
#include <stdio.h>
extern int meaning_of_life();
int main() {
printf("Test: The meaning of life is %d\n", meaning_of_life());
return 0;
}
However, when I try to compile with gcc/Strawberry, I get:
C:\>gcc -o scriptedmain scriptedmain.c scriptedmain.h
c:/strawberry/c/bin/../lib/gcc/i686-w64-mingw32/4.4.3/../../../../i686-w64-mingw32/lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o): In function `main':
/opt/W64_156151-src.32/build-crt/../mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain#16'
collect2: ld returned 1 exit status
And when I try to compile with gcc/MinGW, I get:
$ gcc -o scriptedmain -mwindows scriptedmain.c scriptedmain.h
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0x104): undefined reference to `WinMain#16'
collect2: ld returned 1 exit status
How can I get GCC in Windows to recognize the __attribute__((weak)) syntax?
Also, G++ shows the same error.
I found a solution that works in Windows and in Unix: Simply wrap main() in preprocessor instructions that omits it unless explicit compiler flags are set.
scriptedmain.c:
#include <stdio.h>
int meaning_of_life() {
return 42;
}
#ifdef SCRIPTEDMAIN
int main() {
printf("Main: The meaning of life is %d\n", meaning_of_life());
return 0;
}
#endif
Now main() will be entirely omitted unless you compile with
gcc -o scriptedmain -DSCRIPTEDMAIN scriptedmain.c scriptedmain.h
This code is safe to import into other C code, because the preprocessor will strip out main(), leaving you to code your own main. The best part is that this solution no longer depends on obscure compiler macros, only simple preprocessor instructions. This solution works for C++ as well.
This isn't good practice in C regardless of operating system. Best practice in C for anything complicated enough to be worth separating into library and driver is to put main in a file all by itself.
I am having issues with usage of log10f().
I am compiling the program on Linux (2.6.28-11-generic) and using gcc (3.4.6).
The following source compiles and prints 1.000000 on execution.
#include <stdio.h>
#include <math.h>
int main() {
printf("%f\n", log10f(10));
return 0;
}
while the below one doesn't and throws up link error:
#include <stdio.h>
#include <math.h>
int main() {
printf("%f\n", log10f(100));
return 0;
}
Error : Undefined reference to log10f
Is the log10f() not defined as part of standard math library (Man pages indicate that it is part of math library)?
Why is that the second example doesn't compile?
That's because the required libm.a library is not linked into the executable automatically.
You have to add the -lm parameter to gcc. Then the linker will also link libm.a into your executable.