I've been trying to get mruby set up for use in C, but I've only had success compiling a simple "hello world" example. Other examples won't compile: when I try to compile https://github.com/mruby/mruby/blob/master/tools/mrbc/mrbc.c, I get this:
gcc -Iinclude hello.c libmruby_core.a libmruby.a -lm -o hello
hello.c: In function ‘parse_args’:
hello.c:119:24: error: ‘DUMP_DEBUG_INFO’ undeclared (first use in this function)
args->flags |= DUMP_DEBUG_INFO;
^
hello.c:119:24: note: each undeclared identifier is reported only once for each function it appears in
hello.c:122:23: error: ‘DUMP_ENDIAN_BIG’ undeclared (first use in this function)
args->flags = DUMP_ENDIAN_BIG | (args->flags & DUMP_DEBUG_INFO);
^
hello.c:125:23: error: ‘DUMP_ENDIAN_LIL’ undeclared (first use in this function)
args->flags = DUMP_ENDIAN_LIL | (args->flags & DUMP_DEBUG_INFO);
^
hello.c:154:57: error: ‘DUMP_ENDIAN_MASK’ undeclared (first use in this function)
if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) {
When I try to compile the 'more complex example' from http://matt.aimonetti.net/posts/2012/04/25/getting-started-with-mruby/, in the way they suggest (gcc -Iinclude hello.c lib/libmruby.a -lm -o hello.out) (actually: in a similar way. I've tried both ways.) I get this:
gcc -Iinclude hello.c libmruby.a -lm -o hellohello.c: In function ‘main’:
hello.c:17:7: error: too few arguments to function ‘mrb_parse_string’
p = mrb_parse_string(mrb, code);
^
In file included from /home/neo/Projects/MrubyHs/mruby-1.1.0/include/mruby/irep.h:14:0,
from /home/neo/Projects/MrubyHs/mruby-1.1.0/include/mruby/proc.h:10,
from hello.c:6:
/home/neo/Projects/MrubyHs/mruby-1.1.0/include/mruby/compile.h:170:34: note: declared here
MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
^
hello.c:19:5: warning: assignment makes integer from pointer without a cast
n = mrb_generate_code(mrb, p);
^
hello.c:20:37: error: ‘mrb_state’ has no member named ‘irep’
mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
^
Looks like I'm missing some file or something, but I'm not sure what.
I'm using mruby 1.1.0. I have mruby-1.1.0/include which contains mrbconf.h, mruby.h, and a folder mruby in the gcc search path, and mruby-1.1.0/build/host/lib in LIBRARY_PATH (even though in my examples of what went wrong I just put them in the same folder as where I'm compiling).
Any idea what's wrong with my installation and/or how I'm compiling?
You are trying to compile a newer version of mrbc.c with an older version of mruby. Those #defines were added after 1.1.0 was released. It works for me if I use the version of mruby currently in the git repo:
$ make
...
$ gcc -Iinclude build/host/lib/libmruby.a mrbc.c
$ ./a.out
./a.out: no program file given
As for the second problem, mrb_parse_string was changed to accept an mrb_context* as the third argument in July 2012, so you may want to look into updating your code to use the new API.
Related
I'm compiling a Fortran code to obtain shared library .so. In the code it uses a module. The compiling has no problem while it reports undefined symbol error when opening the .so library.
Code mesh_map.F are as follows:
#include "cfx5ext.h"
dllexport(mesh_map)
SUBROUTINE mesh_map (CZ, DZ, IZ, LZ, RZ)
USE EXTRA_FLUID2
USE ISO_C_BINDING
USE IFPORT
IMPLICIT NONE
CHARACTER*(1) CZ(*)
DOUBLE PRECISION DZ(*)
INTEGER IZ(*)
LOGICAL LZ(*)
REAL RZ(*)
MAP_STATUS = 1
END
extra_fluid2.f90:
Module EXTRA_FLUID2
INTEGER :: map_status = 0
end module EXTRA_FLUID2
Compiling command:
ifort -c extra_fluid2.f90
/home/xxx/intel/oneapi/compiler/2021.4.0/linux/bin/intel64/ifort -fpic -assume 2underscore -check uninit -warn declarations -diag-error 6717 -ftz -O2 -fp-speculation=safe -fp-model=precise -fp-model=source -fimf-arch-consistency=true -qno-opt-dynamic-align -fpe0 -fomit-frame-pointer -real-size 32 -integer-size 32 -I/usr/ansys_inc/v192/CFX/include -o linux-amd64/ifort/mesh_map.o -c mesh_map.F
-lrt/xxx/intel/oneapi/compiler/2021.4.0/linux/bin/intel64/ifort -shared -o ./linux-amd64/ifort/libmesh_map.so linux-amd64/ifort/mesh_map.o extra_fluid2.o
When I check the .so library using:
ldd -r libmesh_map.so
The result shows as:
undefined symbol: extra_fluid2_mp_map_status__ (./libmesh_map.so)
How can I fix this? Thanks.
You must use -assume 2underscore in both compilations, using/not using the option cannot be mixed.
Also extra_fluid2.f90 should be compiled with option -fpic. It's generally a bad idea to use different sets of flags for files that are supposed to go into the same executable or shared object.
Not a duplicate; Answers on various forums didn't fix the problem.
I am running GCC through commands and I am getting undefined references from SDL even though it appears like I linked SDL correctly, how do I stop from getting those undefined references ?
I do not get undefined references from mingw, just SDL.
This is my command: (all the libraries are being located by GCC from what I can tell)
gcc main.c ^
-o app.exe ^
-I "C:\__coding\tools\SDL2-2.0.10\x86_64-w64-mingw32\include\SDL2" ^
-L "C:\__coding\tools\MinGW\lib\" ^
-l "libmingw32.a" ^
-L "C:\__coding\tools\SDL2-2.0.10\x86_64-w64-mingw32\lib" ^
-l "libSDL2main.a" ^
-l "libSDL2.a"
This is the output:
C:...\main.c:(.text+0xe): undefined reference to 'SDL_Init'
C:...\main.c:(.text+0x13): undefined reference to 'SDL_Quit'
c:/__coding/tools/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\...\AppData\Local\Temp\ccqsLSRk.o: bad reloc address 0x20 in section '.eh_frame'
c:/__coding/tools/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
main.c includes SDL.h and just runs SDL_Init() and SDL_Quit().
I also get the classic undefined reference to "winmain" when I remove SDL_Init() and SDL_Quit().
Thanks alot.
I tried my code on my computer which is running MinGW GCC 5.1.0.
When I enter :
g++ hope.cpp -o hope -I D:\armadillo-7.600.2\include
The cmd show me:
hope.cpp:183:26: error: 'stoi' was not declared in this scope
Point_Num = stoi(temp[1]);//number of point
^
hope.cpp:190:34: error: 'stof' was not declared in this scope
Point(i, 0) = stof(temp[travel]);
But when I enter:
g++ hope.cpp -o hope -I D:\armadillo-7.600.2\include -std=c++11
The cmd show me:
C:\Users\von77\AppData\Local\Temp\ccXdhQzS.o:hope.cpp:(.text$_ZN4arma7op_norm21vec_norm_1_direct_stdIdEET_RKNS_3MatIS2_EE[_ZN4arma7op_norm21vec_norm_1_direct_stdIdEET_RKNS_3MatIS2_EE]+0x7b): undefined reference to `dasum_'
C:\Users\von77\AppData\Local\Temp\ccXdhQzS.o:hope.cpp:(.text$_ZN4arma7op_norm21vec_norm_2_direct_stdIdEET_RKNS_3MatIS2_EE[_ZN4arma7op_norm21vec_norm_2_direct_stdIdEET_RKNS_3MatIS2_EE]+0x7f): undefined reference to `dnrm2_'
C:\Users\von77\AppData\Local\Temp\ccXdhQzS.o:hope.cpp:(.text$_ZN4arma4blas3dotIdEET_yPKS2_S4_[_ZN4arma4blas3dotIdEET_yPKS2_S4_]+0x3f): undefined reference to `ddot_'
C:\Users\von77\AppData\Local\Temp\ccXdhQzS.o:hope.cpp:(.text$_ZN4arma6lapack5gesddIdEEvPcPiS3_PT_S3_S5_S5_S3_S5_S3_S5_S3_S3_S3_[_ZN4arma6lapack5gesddIdEEvPcPiS3_PT_S3_S5_S5_S3_S5_S3_S5_S3_S3_S3_]+0x8c): undefined reference to `dgesdd_'
collect2.exe: error: ld returned 1 exit status
And after I use atoi instead of stoi:
I got the same result as "g++ hope.cpp -o hope -I D:\armadillo-7.600.2\include -std=c++11".
you need to include the string header
#include <string>
and you need to specify the namespace
std::stoi(temp[1]);
I'd like to use a single (cross-)compiler to compile code for different ARM calling conventions: since I always want to use floating point and NEON instructions, I just want to select the hard-float calling convention or the soft-float (softfp) calling convention.
My compiler defaults to hard-float, but it supports both architectures that I need:
$ arm-linux-gnueabihf-gcc -print-multi-lib
.;
arm-linux-gnueabi;#marm#march=armv4t#mfloat-abi=soft
$
When I compile with the default parameters:
$ arm-linux-gnueabihf-g++ -Wall -o hello_world_armhf hello_world.cpp
It succeeds without any errors.
If I compile with the parameters returned by -print-multi-lib:
$ arm-linux-gnueabihf-g++ -marm -march=armv4t -mfloat-abi=soft -Wall -o hello_world hello_world.cpp
It again compiles without error (By the way, how can I test that the resultant code is hard- or soft-float?)
Unfortunately, if I try this:
$ arm-linux-gnueabihf-g++ -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon -Wall -o hello_world hello_world.cpp
[...]/gcc/bin/../lib/gcc/arm-linux-gnueabihf/4.7.3/../../../../arm-linux-gnueabihf/bin/ld: error: hello_world uses VFP register arguments, /tmp/ccwvfDJo.o does not
[...]/gcc/bin/../lib/gcc/arm-linux-gnueabihf/4.7.3/../../../../arm-linux-gnueabihf/bin/ld: failed to merge target specific data of file /tmp/ccwvfDJo.o
collect2: error: ld returned 1 exit status
$
I've tested some other permutations of the parameters, but it seems that anything other than the combination shown by -print-multi-lib results in an error.
I've read ARM compilation error, VFP registered used by executable, not object file but the problem there was that some parts of the binary were soft- and some were hard-float. I have a single C++ file to compile...
What parameter(s) I miss to be able to compile with -march=armv7-a -mthumb-interwork -mfloat-abi=softfp -mfpu=neon?
How is it possible that the error is about VFP register arguments while I explicitly have -mfloat-abi=softfp in the command line which prohibits VFP register arguments?
Thanks!
For the records, hello_world.cpp contains the following:
#include <iostream>
int main()
{
std::cout << "Hello, world!" << std::endl;
return 0;
}
You need another compiler with corresponding multilib support.
You can check multilib support with next command.
arm-none-eabi-gcc -print-multi-lib
.;
thumb;#mthumb
fpu;#mfloat-abi=hard
armv6-m;#mthumb#march=armv6s-m
armv7-m;#mthumb#march=armv7-m
armv7e-m;#mthumb#march=armv7e-m
armv7-ar/thumb;#mthumb#march=armv7
cortex-m7;#mthumb#mcpu=cortex-m7
armv7e-m/softfp;#mthumb#march=armv7e-m#mfloat-abi=softfp#mfpu=fpv4-sp-d16
armv7e-m/fpu;#mthumb#march=armv7e-m#mfloat-abi=hard#mfpu=fpv4-sp-d16
armv7-ar/thumb/softfp;#mthumb#march=armv7#mfloat-abi=softfp#mfpu=vfpv3-d16
armv7-ar/thumb/fpu;#mthumb#march=armv7#mfloat-abi=hard#mfpu=vfpv3-d16
cortex-m7/softfp/fpv5-sp-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=softfp#mfpu=fpv5-sp-d16
cortex-m7/softfp/fpv5-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=softfp#mfpu=fpv5-d16
cortex-m7/fpu/fpv5-sp-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=hard#mfpu=fpv5-sp-d16
cortex-m7/fpu/fpv5-d16;#mthumb#mcpu=cortex-m7#mfloat-abi=hard#mfpu=fpv5-d16
https://stackoverflow.com/questions/37418986/how-to-interpret-the-output-of-gcc-print-multi-lib
How to interpret the output of gcc -print-multi-lib
With this configuration gcc -mfloat-abi=hard not only will build your files using FPU instructions but also link them with corresponding libs, avoiding "X uses VFP register arguments, Y does not" error.
The above-mentioned -print-multi-lib output produced by gcc with this patch and --with-multilib-list=armv6-m,armv7,armv7-m,armv7e-m,armv7-r,armv7-a,cortex-m7 configuration option.
If you are interested in building your own gcc with Cortex-A series multilib support, just use --with-multilib-list=aprofile configuration option for any arm*-*-* target without any patches (at list with gcc-6.2.0).
As per Linaro FAQ if your compiler prints arm-linux-gnueabi;#marm#march=armv4t#mfloat-abi=soft then you can only use -march=armv4t. If you want to use -march=armv7-a you need to build compiler yourself.
Following link could be helpful in building yourself GCC ARM Builds
It seems to me that gcc can deal with both c and c++ projects,so why is g++/gcc-c++ needed?
What's the difference between g++ and gcc-c++?
gcc will compile C source files as C and C++ source files as C++ if the file has an appropriate extension; however it will not link in the C++ library automatically.
g++ will automatically include the C++ library; by default it will also compile files with extensions that indicate they are C source as C++, instead of as C.
From http://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html#Invoking-G_002b_002b:
C++ source files conventionally use one of the suffixes .C, .cc, .cpp, .CPP, .c++, .cp, or .cxx; C++ header files often use .hh, .hpp, .H, or (for shared template code) .tcc; and preprocessed C++ files use the suffix .ii. GCC recognizes files with these names and compiles them as C++ programs even if you call the compiler the same way as for compiling C programs (usually with the name gcc).
However, the use of gcc does not add the C++ library. g++ is a program that calls GCC and treats .c, .h and .i files as C++ source files instead of C source files unless -x is used, and automatically specifies linking against the C++ library. This program is also useful when precompiling a C header file with a .h extension for use in C++ compilations.
For example, to compile a simple C++ program that writes to the std::cout stream, I can use either (MinGW on Windows):
g++ -o test.exe test.cpp
gcc -o test.exe test.cpp -lstdc++
But if I try:
gcc -o test.exe test.cpp
I get undefined references at link time.
And for the other difference, the following C program:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int* new;
int* p = malloc(sizeof(int));
*p = 42;
new = p;
printf("The answer: %d\n", *new);
return 0;
}
compiles and runs fine using:
gcc -o test.exe test.c
But gives several errors when compiled using:
g++ -o test.exe test.c
Errors:
test.c: In function 'int main()':
test.c:6:10: error: expected unqualified-id before 'new'
test.c:6:10: error: expected initializer before 'new'
test.c:7:32: error: invalid conversion from 'void*' to 'int*'
test.c:10:9: error: expected type-specifier before '=' token
test.c:10:11: error: lvalue required as left operand of assignment
test.c:12:36: error: expected type-specifier before ')' token
As far as I know, g++ uses the correct C++ linker options whereas gcc uses the C linker options (so you may get undefined references, etc.).