Build Duktape for specific platform (ARM 32/ ARM 64) - duktape

I'm going to use Duktape for javascript evaluation for ARM 32/64 platforms.
I want to build Duktape only for specific platform & architecture, not for all range.
It seems, that I can build it successfully:
python tools/configure.py \
--source-directory src-input \
--platform linux \
--architecture arm32 \
--config-metadata config/ \
--option-file arm32_config.yaml \
--output-directory /tmp/arm32
arm32_config.yaml:
DUK_USE_32BIT_PTRS: true
DUK_USE_64BIT_OPS: false
DUK_USE_FATAL_HANDLER: false
Build pass usually.That's great!
On Raspberry Pi (use it just for tests):
I have a hello.c:
#include "duktape.h"
int main(int argc, char *argv[]) {
duk_context *ctx = duk_create_heap_default();
duk_eval_string(ctx, "print('Hello world!');");
duk_destroy_heap(ctx);
return 0;
}
and Makefile.hello file:
DUKTAPE_SOURCES = src/arm32/duktape.c
# Compiler options are quite flexible. GCC versions have a significant impact
# on the size of -Os code, e.g. gcc-4.6 is much worse than gcc-4.5.
CC = gcc
CCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer
CCOPTS += -I./src/arm32 # for combined sources
CCLIBS = -lm
CCOPTS += -DUK_USE_32BIT_PTRS
CCOPTS += -DUK_USE_64BIT_OPS
CCOPTS += -DUK_USE_FATAL_HANDLER
# For debugging, use -O0 -g -ggdb, and don't add -fomit-frame-pointer
hello: $(DUKTAPE_SOURCES) hello.c
$(CC) -o $# $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) hello.c $(CCLIBS)
It also works!
But when I'm trying to start program ./hello I've always recived:
Segmentation fault
Could please point out on my mistakes?What have I missed?
Thank you in advance!
ps: gcc version 4.9.2 (Raspbian 4.9.2-10)

The main problem you are most likely having is that you're working from Duktape master (which will become the 2.0.0 release) which no longer provides a built-in "print()" binding. That causes an error to be thrown.
That error is uncaught because you don't have a protected call wrapping the eval call, so that a fatal error occurs. Since you don't provide a fatal error handler (in duk_create_heap() or via DUK_USE_FATAL_HANDLER) that causes the default fatal error behavior which is to cause an intentional segfault (this is so that a debugger can attach).
So the easiest fix is to define a print() binding and maybe add a fatal error handler and/or a protected call for the eval. Here's an example to add a print() binding (before doing the eval):
static duk_ret_t native_print(duk_context *ctx) {
duk_push_string(ctx, " ");
duk_insert(ctx, 0);
duk_join(ctx, duk_get_top(ctx) - 1);
printf("%s\n", duk_safe_to_string(ctx, -1));
return 0;
}
/* ... before doing eval(): */
duk_push_c_function(ctx, native_print, DUK_VARARGS);
duk_put_global_string(ctx, "print");
Other minor comments:
Duktape duk_config.h detects the platform and target you're building for; Duktape never really builds "for all targets" as far as the resulting binary is concerned. So having multiple platforms in duk_config.h doesn't make the result any bigger for example.
You shouldn't need the values in your arm32_config.yaml. ARM32 should be detected automatically.
The Makefile.hello you're using is (adapted) from Duktape 1.x while the code you're compiling is from Duktape master. The CCOPTS options will be ignored by Duktape master (they go into tools/configure.py) and their format is wrong in the example, e.g. -DUK_USE_FATAL_HANDLER defines the preprocessor value UK_USE_FATAL_HANDLER.

Related

Pytorch Tensor::data_ptr<long long>() not working on Linux

I cannot link my program to pytorch under Linux, get the following error:
/tmp/ccbgkLx2.o: In function `long long* at::Tensor::data<long long>() const':
test.cpp:(.text._ZNK2at6Tensor4dataIxEEPT_v[_ZNK2at6Tensor4dataIxEEPT_v]+0x14): undefined reference to `long long* at::Tensor::data_ptr<long long>() const'
I am building a very simple minimal example:
#include "torch/script.h"
#include <iostream>
int main() {
auto options = torch::TensorOptions().dtype(torch::kInt64);
torch::NoGradGuard no_grad;
auto T = torch::zeros(20, options).view({ 10, 2 });
long long *data = (long long *)T.data<long long>();
data[0] = 1;
return 0;
}
The command used to build it:
g++ -w -std=c++17 -o test-torch test.cpp -D_GLIBCXX_USE_CXX11_ABI=1 -Wl,--whole-archive -ldl -lpthread -Wl,--no-whole-archive -I../libtorch/include -L../libtorch/lib -ltorch -ltorch_cpu -lc10 -Wl,-rpath,../libtorch/lib
Pytorch has been downloaded from the link https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-1.7.0%2Bcpu.zip and unzipped (so I have the libtorch folder next to the folder with test.cpp).
Any ideas how to solve this problem? Same program works just fine under Visual C++.
P.S. I know pytorch is kind of designed for cmake, but I have zero experience with cmake and no desire to write a cmake-based build system for my app. Also, the examples they give are seemingly supposed to only work if pytorch is "installed" in the system. So I cannot just download the .zip with libs? And if I "install" it (e.g. from sources or in whatever other way) on an AVX512 system, will the binary I link to it and distribute to end-users work on non-AVX512? The documentation is completely incomprehensible for newbies.
UPDATE: I tried to do this via CMake following the tutorial https://pytorch.org/cppdocs/installing.html and got exactly the same error. Specifically, I renamed my directory to example-app and the source file to example-app.cpp. Then I created CMakeLists.txt in this directory with the following contents:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
Then
mkdir build
cd build
cmake -DCMAKE_PREFIX_PATH=../../libtorch ..
cmake --build . --config Release
And here's the output:
CMakeFiles/example-app.dir/example-app.cpp.o: In function `long long* at::Tensor::data<long long>() const':
example-app.cpp:(.text._ZNK2at6Tensor4dataIxEEPT_v[_ZNK2at6Tensor4dataIxEEPT_v]+0x14): undefined reference to `long long* at::Tensor::data_ptr<long long>() const'
Makes me think, maybe I forgot to include some header or define some variable?
Oh, this is all on Mint 19.2 (equivalent to Ubuntu 18.04), g++ version is 7.5.0, glibc is 2.27. Compiling with g++-8 gives the same result.
This is not a cmake-related error, it's just how the library was implemented. I do not know why, but it appears that the specialization of T* at::Tensor::data<T> const with T = long long was forgotten/omitted.
If you want to get your signed 64-bits pointer, you can still get it with int64_t:
auto data = T.data<int64_t>();
It's good practice to use these types for which the size is explicit in general, in order to avoid compatibility issues.

linking SDL2 libraries with pkg-config

I am using Ubuntu 14.04LTS. I have installed the SDL2 libraries both by compiling from source (method1 https://askubuntu.com/questions/344512/what-is-the-general-procedure-to-install-development-libraries-in-ubuntu) and using sudo apt-get install libsdl2-dev.
As I understand, the former installed the libraries and headers in /usr/local/(lib and include), while the latter installs them system wide in /usr/(lib and include).
When I tried to compile a simple code to test the functionality:
#include <SDL.h>
#include <stdio.h>
int main(int argc, char* argv[]) {SDL_Window *window;
// Declare a pointer
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
// Create an application window with the following settings:
window = SDL_CreateWindow(
"An SDL2 window", // window title
SDL_WINDOWPOS_UNDEFINED, // initial x position
SDL_WINDOWPOS_UNDEFINED, // initial y position
640, // width, in pixels
480, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
printf("Could not create window: %s\n", SDL_GetError());
return 1;
}
// The window is open: could enter program loop here (see SDL_PollEvent())
SDL_Delay(3000); // Pause execution for 3000 milliseconds, for example
// Close and destroy the window
SDL_DestroyWindow(window);
// Clean up
SDL_Quit();
return 0;
using: g++ sdl_test.cpp -o sdlout
the compiler outputs:
sdltest.cpp:2:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
^
compilation terminated.
if I change to #include <SDL2/SDL.h> I get the following error:
/tmp/cc05JSKn.o: In function `main':
sdltest.cpp:(.text+0x15): undefined reference to `SDL_Init'
sdltest.cpp:(.text+0x3a): undefined reference to `SDL_CreateWindow'
sdltest.cpp:(.text+0x4a): undefined reference to `SDL_GetError'
sdltest.cpp:(.text+0x6d): undefined reference to `SDL_Delay'
sdltest.cpp:(.text+0x79): undefined reference to `SDL_DestroyWindow'
sdltest.cpp:(.text+0x7e): undefined reference to `SDL_Quit'
collect2: error: ld returned 1 exit status
Which are the basic functions, so I assume that the shared object libraries are not linked correctly.
I also tried: g++ -Wall sdltest.cpp -o outsdl -I /usr/local/include -L /usr/local/lib
to specify the paths, but again I get:
sdltest.cpp:2:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
^
compilation terminated.
The only command that worked and successfully compiled, is when using pkg-config g++ sdltest.cpp -o outsdl $(pkg-config --cflags --libs sdl2)
Therefore, I have the following questions:
1) Why is pkg-config necessary and how do compilation and linking flags work?
2) Is it possible to do something else in order to make the compilation command simpler?
3) (if not explained previously) What is the difference between pkg-config and using -I and -L which do not work?
4) what does $(...) actually do in the command line and is it completely the same as `...` ?
Thank you.
The pkg-config command is a more-or-less cross-platform or cross-distro way to provide the correct flags to your compiler to allow it to find header and library files. That way, your system can store files in different locations and everyone can use the same commands to compile your code. It also helps resolve any special requirements of the library you're trying to use.
Using $() is the same as using backticks, so you can execute what is inside the parentheses in order to see what extra arguments are being passed to your compiler to make it work. Here is what I get on my machine when I run pkg-config --cflags --libs sdl2:
-D_REENTRANT -I/usr/include/SDL2 -lSDL2
The reason you're getting SDL.h: No such file or directory is because pkg-config adds -I/usr/include/SDL2 to the include search paths so you can include SDL.h in your code (without the SDL2 subdirectory).
The reason you get undefined reference errors is because you don't have -lSDL2 (which tells the compiler to link libSDL2).

Asio C++11 Thread Exception: The attempted operation is not supported for the type of object referenced

I'm trying to write a HTTPS client connection to iOS and Android using C++11 Asio's header only library (without boost),
and I'm testing the c++ code on Windows 10. (I tested on Windows 8 too, but the problem is the same)
I got an exception, so I write a simple example myself to find out what's happening. This is the code:
#include <iostream>
#include "asio.hpp"
void hello_world_thread() {
std::cout << "Hello world!" << std::endl;
}
int main()
{
asio::thread t(
std::bind(
&hello_world_thread
)
);
t.join();
return 0;
}
And if I run this inside / outside Code::Blocks I got the following exception:
terminate called after throwing an instance of 'std::system_error'
what(): thread: The attempted operation is not supported for the type
of object referenced.
This application has requested the Runtime to terminate it in an
unusual way. Please contact the application's support team for more
information.
The build command is:
x86_64-w64-mingw32-g++.exe -std=c++11 -Wall
-DASIO_STANDALONE -g -Iasio -c D:\Projektek\C++\AsioTeszt\main.cpp -o obj\Debug\main.o
x86_64-w64-mingw32-g++.exe -o bin\Debug\AsioTeszt.exe
obj\Debug\main.o -lws2_32 -static -static-libgcc -static-libstdc++ -m64
I had already tried the -pthread flag, but the error is the same.
MinGW version: gcc version 5.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project)
Asio version: 1.10.6 (And tried with the Dev release too 1.11.0)
Finally I figured out after 3 days of suffering.
The problem was with the MinGW installation, because I selected win32 at the Threads section.
After reinstallation with posix threads selected everything works fine.
Edit: I again run into this problem but I used the Asio thread in another project. So I started remove everything until I had found out what was missing.
#include <map>
Without this it won't work.

Linking GSL library to RcppGSL on Windows machine

I try to link the GSL library to the RcppGSL package. The following is my test function:
# colNorm.cpp
// [[Rcpp::depends(RcppGSL)]]
#include <RcppGSL.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>
extern "C" SEXP colNorm(SEXP sM) {
try {
RcppGSL::matrix<double> M = sM; // create gsl data structures from SEXP
int k = M.ncol();
Rcpp::NumericVector n(k); // to store results
for (int j = 0; j < k; j++) {
RcppGSL::vector_view<double> colview = gsl_matrix_column (M, j);
n[j] = gsl_blas_dnrm2(colview);
}
M.free() ;
return n; // return vector
} catch( std::exception &ex ) {
forward_exception_to_r( ex );
} catch(...) {
::Rf_error( "c++ exception (unknown reason)" );
}
return R_NilValue; // -Wall
}
The GSL library is succesfully linked to the RcppGSL if the following command does not throw a compiler error:
sourceCpp("colNorm.cpp")
Since I am using Windows machine, I need to define environment variables such that RcppGSL knows where the GSL library is located.
I tried editing the environment variable, but the following compiler error shows that the package is still unable to find the GSL library:
g++ -m64 -I"C:/PROGRA~1/R/R-31~1.1/include" -DNDEBUG -I"C:/CodeLibrary/lib"/include - I"C:/PROGRA~1/R/R-31~1.1/library/Rcpp/include" -I"C:/PROGRA~1/R/R-31~1.1/library/RcppGSL/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c colNorm.cpp -o colNorm.o
g++ -m64 -shared -s -static-libgcc -o sourceCpp_38624.dll tmp.def colNorm.o -LC:/CodeLibrary/lib/lib -lgsl -lgslcblas -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lRlapack -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lRblas -lgfortran -Ld:/RCompile/CRANpkg/extralibs64/local/lib/x64 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lR
c:/program files/r/r-3.1.1/rtools/gcc-4.6.3/bin/../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lgsl
c:/program files/r/r-3.1.1/rtools/gcc-4.6.3/bin/../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lgslcblas
collect2: ld returned 1 exit status
I set an environment variable LIB_GSL equal to "C:/CodeLibrary/lib". In the first line, the compiler takes my environment variable and adds /include. In the second line, the compiler adds /lib. Those locations do not exist on my C drive, maybe that's the reason why it cannot find the library.
I would be really happy, if someone with a lot of compiler experience could show how to successfully link a 3rd party library to a package on Windows machine.
Maybe more environment variables need to be defined?
Thanks Dirk for your handholding! I got it finally up and running.
Three things have to be done:
1) Download the local300 folder from your link and allocate folder on your drive. The path cannot contain any whitespaces, i.e. C:/Program Files/local300 will not work but
C:/local300 will work
2) Set the environment variable LIB_GSL equal to this path, e.g. LIB_GSL to C:/local300
3) The compiler looks at LIB_GSL/lib for libgsl.a and libgslcblas.a (-lgsl and -lgslcblas). However, in LIB_GSL/lib are subfolders i386 and x64. I didn't know how to change the place the compiler looks for the files, thus I copied everything from inside x64 and put it into LIB_GSL/lib folder (one folder level above).
This allows RcppGSL to compile code without errors.
Look at this page which is (after a link or two) pointed to from the R Installation and Administration manual, appendix D for Windows.
Expand that, see where it puts headers and the library for GSL and adjust LIB_GSL accordingly.
This is what CRAN itself uses, so we know it works.

static compile glfw

I'm trying to compile glfw as static link on Linux Mint (based on Ubuntu 10.04) using GCC 4.4.3.
Inside my project directory i got "external/glfw" which contains glfw 2.7.1 source. I've compiled it by running "make x11-install" which gives:
/usr/local/include/GL/glfw.h
/usr/local/lib/libglfw.a
/usr/local/lib/pkgconfig/libglfw.pc
i also got this simple code in test.c:
#include <stdio.h>
#include <stdlib.h>
#include "external/glfw/include/GL/glfw.h"
int main( int argc, char const* argv[] )
{
if( !glfwInit() ){
fprintf( stderr, "glfwInit Failed\n" );
}
glfwOpenWindowHint( GLFW_FSAA_SAMPLES, 4 );
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MAJOR, 3 );
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MINOR, 1 );
glfwOpenWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
// Open a window and create its OpenGL context
if( !glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW )){
fprintf( stderr, "glfwOpenWindow failed\n" );
glfwTerminate();
return -1;
}
return 0;
}
i'm trying to compile glfw as static link and compiled the code using gcc with flags:
/usr/bin/gcc `pkg-config --cflags libglfw` -o test test.c \
`pkg-config --libs libglfw` -lXrandr -lX11 -lGLU -lGL -pthread -lm
and it doesn't give me any error. but when i try to execute the binary it shows that i've failed to call glfwOpenWindow.
could any one help me please? thank you for your time guys!
cheers!
P
EDIT 1: I think the problem lies with the linking process and not the code. Because if i have libglfw2 and libglfw-dev installed (ubuntu packages), then the executable runs just fine. What i want here is to have glfw statically linked and not to rely on distro package share libs for the binary to run.
EDIT 2 as per datenwolf suggestion i tried to debug with gdb. i never use gdb before but i use perl debugger a lot. somehow they share a lot of similarities. i recompile glfw and my test.c with -ggdb.
flowing with gdb it shows that my code goes into glfwOpenWindow() which is in "window.c" in glfw source code. since i'm new to gdb i don't know how to evaluate expression or get the value of variables. based on quick search on google all i know is "whatis" to see the date type. but i think my code stops when it reached line 484 in "window.c"
if( wndconfig.glProfile &&
( wndconfig.glMajor < 3 || ( wndconfig.glMajor == 3 && wndconfig.glMinor < 2 ) ) )
{
// Context profiles are only defined for OpenGL version 3.2 and above
return GL_FALSE;
}
now i'm not sure how come using static link glfw thinks i'm not on OpenGL 3.2 and above, while having libglfw2 installed it works just fine?
thanks for your help guys! especially datenwolf!
EDIT 3 Thanks for the help guys. After some help from people in stackoverflow and old nabble I manage to write it down what needs to be done to statically linked GLFW and GLEW and put it on http://www.phacks.net/static-compile-glfw-and-glew/
So your error is that the call to glfwOpenWindow failed? No unresolved symbol or shared object not found messages before even main() gets called? Then you successfully linked against GLFW statically.
I think your problem lies in the parameters you pass to glfwOpenWindow:
glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW )
So you're requesting zero red, green or blue bits per channel, but 32 depth bits. I doubt your system supports that. I'd try
glfwOpenWindow( 1024, 768, 8,8,8,0, 24, 8, GLFW_WINDOW )
that's what most systems support well.
Your example program requests OpenGL 3.1 and a context profile. Profiles are only defined for OpenGL 3.2 and above, which is most likely why glfwOpenWindow fails in this case. To fix this, either request a version above or equal to 3.2, or remove the request for a context profile.
For more information about modern OpenGL context creation with GLX, upon which this part of GLFW is a thin layer, see
http://www.opengl.org/registry/specs/ARB/glx_create_context.txt .

Resources