When use arm-linux-gnueabi-gcc for cross compile. GOOS only support linux and do not support android.
CGO_ENABLED=1 CGO_CFLAGS CC=arm-linux-gnueabi-gcc GOOS=linux GOARCH=arm go build -o hello .
# After build generated hello file
file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, BuildID[sha1]=038c80350b7a0c9e72b10021c66c31c2dbb4df2c, for GNU/Linux 3.2.0, not stripped
As you can see the output file hello with dynamically linked, interpreter /lib/ld-linux.so.3. It can not run in android platform.
./hello
/system/bin/sh: ./hello: No such file or directory
In Android the interpreter should be /system/bin/linker. My question is how to specific dynamic linker with cgo?
As i searched in there. the gcc has params like gcc -o test test.c -Wall -Wl,--dynamic-linker=/system/bin/linker.
you can enable cgo and send these flags to cgo from the comment above import "C" statement:
package main
/*
#cgo LDFLAGS: --dynamic-linker=/lib/ld-linux.so.3
*/
import "C"
func main() {
}
Tell me if this work
Finally i used NDK build for android.
Related
I want to compile a simple program "int main(){return 0;}" to RISC-V processor.
LLVM/Clang version is 9.0 and I want to run the compiled program with a RISC-V simulator like this https://github.com/riscv/riscv-tools
My problem is that I can't list the clang supported targets only the LLC-s whith these commands:
llc --version
llc -march=xxARCHTYPExx -mattr=help
And there is no any type of riscv processor listed.
So I tried to look the triple file: llvm-project\llvm\include\llvm\ADT\Triple.h
and try a command like: clang hello.c -target riscv32 -march=rv32imafd
But I get the following error:
error: unable to create target: 'No available targets are compatible
with triple "riscv32"'
Can somebody help me to how get a valid RISC-V target? I just simple can't compile the program but I know LLVM has a RISC-V support.
LLVM 9 release notes explicitly state that RISC-V support was promoted from experimental to official.
And indeed, on my Fedora 31 machine, the LLVM 9 Fedora package does support RISC-V:
$ llvm-objdump --version | grep riscv
riscv32 - 32-bit RISC-V
riscv64 - 64-bit RISC-V
Also, I can create RISC-V binary code with the LLVM toolchain:
$ clang --target=riscv64 -march=rv64gc rotate.s -c -o rotate.o
$ file rotate.o
rotate.o: ELF 64-bit LSB relocatable, UCB RISC-V, version 1 (SYSV), not stripped
Although it doesn't include a libc for RISC-V targets:
$ clang --target=riscv64 -march=rv64gc hello-world.c -o hello-world
hello-world.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^~~~~~~~~
1 error generated.
However, you don't really need one - you could directly call syscalls for your hello world, e.g.:
$ clang --target=riscv64 -march=rv64gc hello.s -c -o hello.o
$ ld.lld hello.o -o hello
$ spike --isa=RV64gc ~/local/riscv/pk/riscv64-unknown-elf/bin/pk ./hello
bbl loader
Hello World
I don't use clang for linking because it seems that I can't convince clang with -fuse-ld to use another linker besides /usr/bin/ld.
Is it possible?
I have the following Go function I'd like to call from a C program:
// package name: test
package main
import "C"
//export Start
func Start() {
println("Hello world")
}
func main() {
}
I'm using the following command to build the archive
go build -buildmode=c-archive -o test.a main.go
Using gcc I can get this C program working:
#include <stdio.h>
#include "test.h"
int main() {
Start();
return 0;
}
I'm using the following command to build the executable:
gcc main.c sdlgotest.a -o main -lpthread
This all works fine for amd64, but I'd like to use this archive in a aarch64 targed development environment (using libtransistor)
libtransistor build system uses LLVM but it has it's own set of standard includes (libc, etc.) and it doesn't use glibc.
So when I'm trying to get libtransistor to link my archive I get the following errors:
/usr/lib/llvm-5.0/bin/ld.lld: error: undefined symbol: stderr
>>> referenced by gcc_libinit.c:29
>>> 000006.o:(x_cgo_sys_thread_create) in archive ./sdlgotest.a
/usr/lib/llvm-5.0/bin/ld.lld: error: undefined symbol: stderr
>>> referenced by gcc_libinit.c:29
>>> 000006.o:(x_cgo_sys_thread_create) in archive ./sdlgotest.a
libtransistor by the way is compiling the code with flags like this:
-nostdlib -nostdlibinc -isystem /opt/libtransistor/include/
So I guess the problem is that the linker can't resolve those glibc symbols.
Is there a way to compile the Go runtime without those glibc symbols so I can use the archive like I intend to? (without relying on GCC toolchain or glibc)
From the docs:
The default C and C++ compilers may be changed by the CC and CXX environment variables, respectively; those environment variables may include command line options.
So I'd try something like
$ CC=clang go build -buildmode=c-archive -o test.a main.go
and see what happens.
Run go env and see the list of env parameters set to go. You can change certain parameters based on what you need.
Following are some of the samples that I have used to build a shared dll from go program.
GOARCH=386 GOOS=windows CGO_ENABLED=1 GOPATH=`pwd` CC=i686-w64-mingw32-gcc go build -o go-shared-lib.dll -buildmode=c-shared go-shared-libs
GOARCH=amd64 GOOS=windows CGO_ENABLED=1 GOPATH=`pwd` CC=x86_64-w64-mingw32-gcc go build -o go-shared-lib.dll -buildmode=c-shared go-shared-libs
I want to call C code in Golang:
// #cgo CFLAGS: -I/usr/include/c++/8.1.1/bits
// #cgo CXXFLAGS: -std=gnu++11
// #include "c++0x_warning.h"
import "C"
but get error:
In file included from ./main.go:5:
/usr/include/c++/8.1.1/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
So cgo doesn't use CXXFLAGS. I tried -std=c++11 and it doesn't work too. What I do wrong?
$ go version
go version go1.10.3 linux/amd64
Please refer to the following SO question: Difference between CPPFLAGS and CXXFLAGS in GNU Make to figure out which flags you really need in the context of your program.
If you are calling pure C code (and not C++ code), I don't think you will need CXX_FLAGS:
CPPFLAGS are supposed to be flags for the C PreProcessor; CXXFLAGS are flags for the C++ compiler.
You might also want to check your go env. If you really need this flag, you can try to compile your program using env CGO_CXXFLAGS="-std=c++11" go build <YOUR_CODE>.
Consider a.c as containing:
void _start(void);
void _start(void) { while (1); }
With gcc 5.4.0 on Ubuntu, the following command generates an ELF file with type EXEC and no external dependencies:
gcc -o ./a -x c ./a.c -nostartfiles -nostdlib -nodefaultlibs
However, the same command with gcc 6.4.0 on Gentoo yields an ELF file with type DYN that requests the standard program interpreter /lib64/ld-linux-x86-64.so.2.
So, how do I generate a truly standalone EXEC binary with gcc 6.4.0?
You need to build in non-PIE mode to create a position-dependent executable. This consists of two steps:
Compile with -fno-pie.
Link with -no-pie.
Linking code compiled as PIE into a position-dependent executable works, but will results in a performance loss and a larger executable.
Found it. One must specify -no-pie.
For a test I have written a code of matrix multiplication in C(cuda) and compiled it using nvcc to create shared library using following command.
nvcc -c MatMul.cu -o libmatmul.so
Then i wrote a OpenCV code in C and tried to compile with following command.
gcc ImgMul.c `pkg-config --cflags --libs opencv` -L. -L/usr/local/cuda/lib64 -I/usr/local/cuda/include -I. -lmatmul -lcudart -o ImgMul
and I am getting following error.
gputest.c:(.text+0x3f): undefined reference to `matmul'
Could anyone tell me how to include cuda libraries while compiling a code in gcc.
OS: Ubuntu
gcc : 4.4.0
The first point to make is that
nvcc -c MatMul.cu -o libmatmul.so
does not make a shared library, it just compiles to an object file. Shared libraries and object files are not at all the same thing.
That aside, the reason for the symbol not found error is C++ name mangling. Host code in CUDA source files is compiled using the host C++ compiler, not C. So symbol names in the host code emitted by the compiler are subject to name mangling. To get around this, the easiest way is to declare functions which you wish to call from plain C code using the extern "C" declarator (see here for a reasonable overview of the perils of C/C++ interoperability).