I've just bought a new laptop for me on the travel, then on my free time, I've started to test MinGW on it by trying to compile my own OS that is written in C++, then I've created all the files needed and the kernel.cpp:
extern "C" void _main(struct multiboot_data* mbd, unsigned int magic);
void _main( struct multiboot_data* mbd, unsigned int magic )
{
char * boot_loader_name =(char*) ((long*)mbd)[16];
/* Print a letter to screen to see everything is working: */
unsigned char *videoram = (unsigned char *) 0xb8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* forground, background color. */
}
And tried to compile it with g++
G:> g++ -o C:\kernel.o -c kernel.cpp -Wall -Wextra -Werror -nostdlib -nostartfiles -nodefaultlibs
kernel.cpp: In function `void _main(multiboot_data*, unsigned int)':
kernel.cpp:8: warning: unused variable 'boot_loader_name'
kernel.cpp: At global scope:
kernel.cpp:4: warning: unused parameter 'magic'
G:>
But it don't create any binary file at C:/>.
What can I do?
It doesn't create the file because you have -Werror enabled. The warnings you're getting about unused variables are counting as errors, so compilation gets aborted. Just comment them out for the moment:
void _main( struct multiboot_data* mbd, unsigned int /* magic */ )
{
// char * boot_loader_name =(char*) ((long*)mbd)[16];
// ...
}
And it should build fine. Also, shouldn't _main() be declared as just main() and then allowed to be "mangled" into _main() by the compiler? Edit: You probably also want to be using -c to skip the linking phase, assuming you just want the object files.
Did you try creating the .o file in a local directory first? What result did you get?
C:\ is usually blocked for writing on Vista and 7, since it's considered a very sensitive location, and you have to run as administrator to be allowed to do that (as in, explicitly launching the command prompt or g++ with admin rights). The same should apply if you're running on a "regular" (non-admin) user account, even in XP.
Perhaps that's what's happening to you?
Related
Im setting up the bsplib (https://github.com/Zefiros-Software/BSPLib) on a windows system (in VS Code) using WSL. When compiling I get the error message:
test.cpp:4:5: error: conflicting declaration of C function ‘int main()’
4 | int main()
| ^~~~
In file included from /mnt/d/study/software/bsp/include/bsp/bspExt.h:30,
from /mnt/d/study/software/bsp/include/bsp/bsp.h:34,
from test.cpp:2:
/mnt/d/study/software/bsp/include/bsp/bspClass.h:59:12: note: previous declaration ‘int main(int, char**)’
59 | extern int main(int argc, char **argv);
The program is used is just a bare example for BSP:
#include <iostream>
#include "bsp/bsp.h"
int main()
{
bsp_begin(bsp_nprocs());
int s = bsp_pid();
int p = bsp_nprocs();
printf("Hello World from processor %d / %d", s, p);
bsp_end();
return 0;
}
Compiled with:
g++ -I/mnt/d/study/software/bsp/include -g -lpthread -o main test.cpp
To my (quite limited) knowledge, the 'extern' in the header file should prevent the compiler from labelling the main as 'duplicate' of some sort. Im mostly interested in some of BSPs functionalities as part of a class of mine, that sadly does not include any support on the installation. What I've done so far:
Copied the include files from the repo
Added the include path to the compilation (-I Flag) and the -lpthread as instructed by the class script
Added the include path to the configuration (c_cpp_properties.json) [tested both with and without this, no difference]
Due to the many possible sources of that error (program, compiler, wsl, library, configuration, vs code, my stupidity) I cant determine where I am mistaken, nor am I able to find online resources to that combination.
I run an up to date debian testing (with kernel 4.19).
Helpers are not found on my system (but they exist in the header, Qt jumps to them)
#include "bpf/bpf.h"
int main (){
int r = bpf_create_map(BPF_MAP_TYPE_ARRAY,1,1,1,0);
return 0;
}
Compilation results in
undefined reference to `bpf_create_map(bpf_map_type, int, int, int, unsigned int)'
compiled with
g++ -c -pipe -g -std=gnu++1z -Wall -W -fPIC -DQT_QML_DEBUG -I. -I../../Qt/5.13.0/gcc_64/mkspecs/linux-g++ -o main.o main.cpp
g++ -lbpf -o server main.o
Same result with
g++ main.cpp -lbpf -o out
I have the libbpf-dev installed as well and i have the associated libraries (a and so).
What is wrong?
Update
even the following code won't work
#include <linux/bpf.h>
int main (){
//int r = bpf_create_map(BPF_MAP_TYPE_ARRAY,1,1,1,0);
bpf_attr attr = {};
attr.map_type = BPF_MAP_TYPE_ARRAY;
attr.key_size = 1;
attr.value_size = 1;
attr.max_entries = 1;
bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
return 0;
}
results in
error: 'bpf' was not declared in this scope
Update2:
BTW, key size is mandated to be 4 and not 1; but it is a point aside, that was unrelated to my problem here.
Namespace issue due to compiling in C++, you probably want:
extern "C" {
#include "bpf/bpf.h"
}
int main()...
Regarding your second error (error: 'bpf' was not declared in this scope), this is not directly related to libbpf, this is because there is no function simply called bpf() to actually perform the syscall. Instead you have to use the syscall number. For example, libbpf defines the following:
static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
unsigned int size)
{
return syscall(__NR_bpf, cmd, attr, size);
}
... and uses sys_bpf() after that, the same way you try to call bpf() in your sample.
For the record, “BPF helpers” often designates BPF functions that you call from within a BPF program, which is not the case here. Hence some confusion in the comments, I believe.
I'trying to compile the c code with mex for MATLAB 2013a 64 under win7 64
http://www.cs.cornell.edu/People/tj/svm%5Flight/svm_perf.html
According to info from this site the SVMPerf MATLAB interface was done by O Luaces
but only for Linux and MACos and it don't compile under windows
http://www.aic.uniovi.es/~oluaces/Oscars_Home_Page/Personal.html
for this i installed gnumex to have access to gcc for MATLAB and this is ok.
then I compiled with mex and created object files for all involved c programs according
to make file from SVMPerf.
I also compiled mex_interface.cpp file which was used for MATLAB interface under LINUX.
However when I try to link all files I'm getting following error related to my_malloc
svm_learn_main.obj:svm_learn_main.c:(.text+0x470): first defined here
svm_struct_main.obj:svm_struct_main.c:(.text.startup+0x0): multiple definition of
`main'
svm_learn_main.obj:svm_learn_main.c:(.text.startup+0x0): first defined here
Cannot export mexFunction: symbol not defined
mex_interface.obj:mex_interface.cpp:(.text+0x94): undefined reference to
`my_malloc(unsigned long long)'
mex_interface.obj:mex_interface.cpp:(.text+0x218): undefined reference to
`my_malloc(unsigned long long)'
C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.9.0/../../../../x86_64-w64-mingw32
/bin/ld.exe: mex_interface.obj: bad reloc address 0x0 in section `.pdata'
collect2.exe: error: ld returned 1 exit status
link command: gcc -shared C:\Users\KRZYSZ~1\AppData\Roaming\MATHWO~1\MATLAB\R2013a
\gnumex\mex.def -o svm_perf_classify.mexw64 -LC:\Users\KRZYSZ~1\AppData\Roaming
\MATHWO~1\MATLAB\R2013a\gnumex -s mex_interface.obj my_malloc.obj svm_learn_main.obj
svm_learn.obj svm_common.obj svm_hideo.obj svm_struct_learn.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj svm_struct_api.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj -llibmx -llibmex
-llibmat
I believe it points to this code. my_malloc compiles OK. Any idea ??
void create_argc_argv(const mxArray *options,int *argc,char **argv[]) {
// convert the matlab string of options into a CLI-like input (argc and argv)
*argc=1;
mwSize buflen = mxGetN(options)*sizeof(mxChar)+1;
char *buf = mxMalloc(buflen);
// Copy the string data into buf
mxGetString(options, buf, buflen);
// and separate in argv[]
char **ap, **argv_ptr=(char **)my_malloc(MAX_ARGVS*sizeof(char *));
argv_ptr[0]="OLR";
for (ap = (argv_ptr+1); (*ap = strsep(&buf, " \t")) != NULL;)
if (**ap != '\0') {
(*argc)++;
if (++ap >= &argv_ptr[MAX_ARGVS])
break;
}
// 'buf' shouldn't be freed, since it is converted to the different 'argv[i]'
// by setting to '\0' the tabs and white spaces between options
// (this trick was taken from the 'strsep' man page)
// so, we don't make mxFree(buf);
*argv=argv_ptr;
}
my mex command looks like this
mex -largeArrayDims -DWIN -output svm_perf_classify mex_interface.cpp
svm_learn_main.obj svm_learn.obj svm_common.obj svm_hideo.obj svm_struct_learn.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj svm_struct_api.obj
svm_struct_classify.obj svm_struct_common.obj svm_struct_main.obj
It looks like the issue you have isn't MEX related, as the main function is declared more than once. Which makes it hard for the compiler to know where to start running the code. If you have public functions you want to use in svm_learn_main or svm_struct_main, you'll want to separate those from the files containing the main function.
mex -largeArrayDims -DWIN -output svm_perf_classify mex_interface.cpp
svm_perf_classify does not have a source file extension(.c or .cpp or other), so it's considered a executable by compiler.
Related topic:
Why does const imply internal linkage in c++, when it doesn't in C?
I was following GCC visibility wiki to add visibility to my shared library.
It generates a warning when I'm compiling my source file
warning: 'visibility' attribute ignored [-Wattributes]
Here's my code:
// my_shared_lib.h
#if __GNUC__ >= 4
#define DLL_API __attribute__((visibility("default")))
#define DLL_LOCAL __attribute__((visibility("hidden")))
#else
#define DLL_API
#define DLL_LOCAL
#endif
DLL_LOCAL const int my_local_var;
It generate following warning while compiling:
my_shared_lib.h: 'visibility' attribute ignored [-Wattributes]
DLL_LOCAL const int my_local_var;
^
Here's the entire building message:
make all
Building file: ../src/my_shared_lib.cc
Invoking: Cross G++ Compiler
g++-mp-4.8 -O3 -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"src/my_shared_lib.d" -MT"src/my_shared_lib.d" -o "src/my_shared_lib.o" "../src/my_shared_lib.cc"
my_shared_lib.h: 'visibility' attribute ignored [-Wattributes]
DLL_LOCAL const int my_local_var;
^
Finished building: ../src/my_shared_lib.cc
Can anyone tell me how to silent this warning and why this warning happened?
Is it because const variable are hidden by default?
PS.
I'm using g++ 4.8
You can silence the warning by passing -Wno-attributes to the compilation.
The warning is happening because, as the related question and answer mentions, in C++ const objects automatically have internal linkage unless they're explicitly marked as extern; i.e. they're hidden by default. The rationale is to encourage putting these const values into header files as-is (i.e. in the form const int x = value;). If they were public by default, then you would suffer multiple-linkage issues if the same variable appeared across multiple .cpp or .o files, which is what would happen if they were placed in .h files without the local linkage rule.
You should also be seeing a warning/error:
my_shared_lib.h:...: error: uninitialized const 'my_local_var' [-fpermissive]
which is a variation of the error because the const is implicitly static unless otherwise mentioned.
How do you fix this?
Firstly, use the const properly in the header when using C++, it's:
const int my_local_var = VALUE;
If you're sharing this .h file amongst C and C++ code then your choices are:
Don't make it const - that's actually meaningless for the C code, and prevents you from accomplishing the private, declared in the header and defined in a .c file but not exposed in the resulting .so
Use a #define - yes, it's ugly, but this is more semantically correct than using a const for C code as it prevents you from accidentally changing the value by erroneous assignment.
declare it in the .h as:
...
DLL_LOCAL extern const int my_local_var;
and then define it in the .cc/.cpp file as:
#include "my_shared_lib.h"
const int my_local_var = 42;
You need to add in the #include or else it doesn't get the extern which allows it to be exposed for linking in the .o files that make up the .so without getting it exposed in the .so itself.
and so we have (on a mac, but the premise is the same):
Header:
$ cat wodge.h
#define PRIVATE __attribute__((visibility("hidden")))
#define PUBLIC __attribute__((visibility("default")))
PRIVATE extern const int my_local_var;
int do_with_x(int x);
First C++ file:
$ cat wodge.cc
#include "wodge.h"
int
do_with_x(int y)
{
return my_local_var * y;
}
Second C++ file - definition of value:
$ cat wodge2.cc
#include "wodge.h"
const int my_local_var = 42;
Compile and show the resulting symbol table:
$ g++-4.8 -c -O3 -Wall -o wodge.o wodge.cc
$ g++-4.8 -c -O3 -Wall -o wodge2.o wodge2.cc
$ g++-4.8 -shared -o foo.dylib *.o
$ nm foo.dylib
0000000000000fb0 T __Z9do_with_xi
0000000000000fbc s _my_local_var
U dyld_stub_binder
I have a header (only) file constants.h, where I define all the constant variables, to be used later in the library. However, there is one variable, which I would like to define run-time in an implementation file. I tried to do something like this:
constant.hpp
extern const unsigned int numTests;
somewhere else in run.cpp
const unsigned int numTests = 10;
and, then yet another file tester.cpp uses
if ( n < numTests) {
// do something
}
Now, when I compile it, I get a linker error in tester.o as undefined symbol numTests. I sort of understand why this is happening: the tester.cpp includes constants.hpp and not the run.cpp and so, it can not find the constant numTests initialized in run.cpp.
Is there any better way to do it?
TIA,
Nikhil
Make sure you are compiling both run.cpp and tester.cpp when you compile your program and you won't get a linker error.
You need to link run.o when creating the executable:
g++ -o tester tester.cpp run.o ; for GNU C++
(Check your own compiler's command line switches if you're not using GNU C++)