Cross compiling and CMake? - linux

I'm building an embedded Linux system for ARM, and one of the applications is using CMake:
cmake \
-D CMAKE_C_COMPILER=/opt/arm-toolchain/bin/arm-linux-gnueabihf-gcc \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_SYSTEM_NAME=Linux \
-D CMAKE_INSTALL_PREFIX=/mnt/system_rootfs ../app_src_dir
If CMake is executed like this, it searches the whole file system for libraries, header files etc.
How can I restrict CMake to ONLY search /opt/arm-toolchain and /mnt/system_rootfs for header files, libraries and programs?
Build system is Debian Wheezy and CMake version is 2.8.9

You can use CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH environment variable for searching header files, libraries.
cmake \
-D CMAKE_C_COMPILER=/opt/arm-toolchain/bin/arm-linux-gnueabihf-gcc \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_SYSTEM_NAME=Linux \
-D CMAKE_INSTALL_PREFIX=/mnt/system_rootfs ../app_src_dir
-D CMAKE_INCLUDE_PATH=/include/path
-D CMAKE_LIBRARY_PATH=/lib/path/

Related

installing OpenCV on centos 8

I'm trying to install opencv on my centos8 server and use it in my java program. I followed the instructions mentioned here, but when I change directory to /opencv/build folder and run
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=ON -D
INSTALL_PYTHON_EXAMPLES=ON -D OPENCV_GENERATE_PKGCONFIG=ON -D
OPENCV_EXTRA_MODULES_PATH=~/opencv_build/opencv_contrib/modules -D BUILD_EXAMPLES=ON ..
,I get the following error:
CMake Error: The source directory "/root/opencv_build" does not appear to contain CMakeLists.txt.
how to solve this issue? the solutions here didn't help.

Cross compile on Alpine Linux targeting debian : undefined reference to `__res_init'

I am trying to setup CI in GitLab.
Building OS: Alpine Linux Container, actually it is Docker-In-Docker
image. (see Dockerfile below)
Targeting OS: x86_64-unknown-linux-gnu
Building Tool: cross https://github.com/rust-embedded/cross
Error: undefined reference to `__res_init'
Full log : https://github.com/rust-embedded/cross/files/4894721/build.log
Here is Dockerfile of Alpine running cross
FROM docker:stable-dind
RUN apk add --no-cache ca-certificates gcc mingw-w64-gcc libc-dev musl-dev
# Copied from https://github.com/rust-lang/docker-rust/blob/6314c6bc3d54d5b9284458c6a9061ef5766c9607/1.44.1/alpine3.12/Dockerfile
ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo \
PATH=/usr/local/cargo/bin:$PATH \
RUST_VERSION=1.44.1
RUN set -eux; \
url="https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-unknown-linux-musl/rustup-init"; \
wget "$url"; \
echo "0c86d467982bdf5c4b8d844bf8c3f7fc602cc4ac30b29262b8941d6d8b363d7e *rustup-init" | sha256sum -c -; \
chmod +x rustup-init; \
./rustup-init -y --no-modify-path --profile minimal --default-toolchain $RUST_VERSION; \
rm rustup-init; \
chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
rustup --version; \
cargo --version; \
rustc --version;
RUN cargo install cross
RUN rustup target add x86_64-pc-windows-gnu
RUN rustup target add x86_64-unknown-linux-gnu
ENV CROSS_DOCKER_IN_DOCKER=true
RUN mkdir ~/.cargo/ && \
printf "\n[target.x86_64-pc-windows-gnu]" >> ~/.cargo/config && \
printf "\nlinker = \"/usr/bin/x86_64-w64-mingw32-gcc\"" >> ~/.cargo/config

Creating a new FreeBSD port for an application that uses NPM, not Make

I'm creating a FreeBSD port for an application (Cypress) that doesn't use Make; instead, it uses NPM:
npm run binary-build-linux
cd cli
npm run build
There are two options I can see:
Add a Makefile to the work directory as a patch.
Convince the upstream maintainers to take a Makefile that would be solely used by this port.
I'm wondering if there's a third option I've missed: modify my port's Makefile to run a series of shell commands in lieu of a Makefile? Having read the porter's handbook I can't see any way of doing that though.
You don't necessarily need to use make for example, this is port is using go in the do-build target: (check the Additional Build Targets, target-OPT-on and target-OPT-off:
do-build:
#cd ${WRKSRC}/src/github.com/${GH_ACCOUNT}/${GH_PROJECT}; \
${SETENV} ${MAKE_ENV} ${BUILD_ENV} GOPATH=${WRKSRC} go build -ldflags \
"-s -w -X main.version=${PORTVERSION}" -o immortal cmd/immortal/main.go;
#cd ${WRKSRC}/src/github.com/${GH_ACCOUNT}/${GH_PROJECT}; \
${SETENV} ${MAKE_ENV} ${BUILD_ENV} GOPATH=${WRKSRC} go build -ldflags \
"-s -w -X main.version=${PORTVERSION}" -o immortalctl cmd/immortalctl/main.go;
#cd ${WRKSRC}/src/github.com/${GH_ACCOUNT}/${GH_PROJECT}; \
${SETENV} ${MAKE_ENV} ${BUILD_ENV} GOPATH=${WRKSRC} go build -ldflags \
"-s -w -X main.version=${PORTVERSION}" -o immortaldir cmd/immortaldir/main.go;
This other port using node:
do-build:
#(cd ${WRKSRC}/public ; node ./bundler.js )
#(cd ${WRKSRC} ; go-bindata -o util/bindata.go -pkg util config.json db/migrations/ public/css public/html public/html/projects public/html/projects/repositories public/html/projects/inventory public/html/projects/templates public/html/projects/users public/html/projects/environment public/html/projects/keys public/html/users public/html/auth public/img public/js public/js/services public/js/controllers public/js/controllers/projects public/js/routes public/js/factories public/node_modules public/node_modules/lodash public/node_modules/lodash/fp public/node_modules/async public/node_modules/async/dist public/node_modules/async/internal public/vendor public/vendor/fontawesome public/vendor/fontawesome/less public/vendor/fontawesome/fonts public/vendor/sweetalert public/vendor/moment public/vendor/bootstrap public/vendor/bootstrap/fonts public/vendor/bootstrap/dist public/vendor/bootstrap/dist/css public/vendor/bootstrap/dist/fonts public/vendor/bootstrap/dist/js public/vendor/bootstrap/less public/vendor/bootstrap/less/mixins public/vendor/angular-loading-bar )
#(cd ${WRKSRC}/cli ; ${SETENV} ${MAKE_ENV} GOPATH=${WRKSRC} go build -o semaphore ./... )
Both ports use the BUILD_DEPENDS (check the Dependencies in the porter handbook)
BUILD_DEPENDS= ${LOCALBASE}/bin/go:lang/go \
${LOCALBASE}/bin/go-bindata:devel/go-bindata \
npm>=0:www/npm

Is it possible to change glibc's default rpath? [duplicate]

I'm trying to build and install my own gcc 4.7.2 in /usr/local to use in place of the gcc 4.4.6 in /usr. (This is on CentOS 6.3.)
gcc makes executables and dynamic libraries that dynamically link to its own dynamic libraries, e.g. libstdc++.so. How do I build and install gcc so that the generated binaries automatically get a linker -rpath option (-rpath /usr/local/lib64) that causes dynamic libraries in /usr/local/lib64 to be linked instead of those in /usr/lib64 or /lib64?
If it works properly, after I build an executable with the gcc without specifying "-Wl,-rpath=/usr/local/lib64", when I ldd the executable, it should show /usr/local/lib64/libstdc++.so.6 instead of /usr/lib64/libstdc++.so.6. Similarly for the libgcc_s.so.1.
I have tried different approaches, including specifying LDFLAGS_FOR_TARGET=-Wl,-rpath=/usr/local/lib64,-rpath=/usr/local/lib on the 'configure' command-line, but nothing worked.
If you don't want to export paths there's an alternative solution:
with your toolchain in the PATH:
gcc -dumpspecs > specsfile
edit specsfile and in the section link add your -rpath example:
*link:
%{!static:--eh-frame-hdr} -m %(link_emulation) %{shared:-shared} %{!shared: %{!static: %{rdynamic:-export-dynamic} -dynamic-linker %(dynamic_linker)} %{static:-static}} -rpath /usr/local/lib64
at this point you can test if it work with:
g++ -specs=specsfile test.cpp
readelf -d a.out |grep RPATH
if it work you can make it permanent (no need to pass -specs everytime)
strace -fF -o /tmp/g++.log g++ test.cpp
grep specs /tmp/g++.log
the grep should show the paths where gcc look for the default specs file.
The specs files are flexible enough to allow conditional linking depending on variables, example:
{!static: %{mabi=n32:-rpath-link %R/lib32:%R/usr/lib32} %{mabi=64:-rpath-link %R/lib64:%R/usr/lib64} %{mabi=32:-rpath-link %R/lib:%R/usr/lib}}
should use different and multiple paths depending on mabi (untested, yet), %R should be the sysroot path, can be changed with needed full path.
There's also a --with-specs= option gcc configure eventually to be used at build time, not clear to me yet how to use with the link section (working on it).
--with-specs="%{shared:-Wl,-rpath -Wl,$(DESTDIR)/lib}%{!shared:-Wl,-rpath -Wl,$(DESTDIR)/lib}"
It work, I used both shared and not !shared just for test, probably some smarter condition should be used, note that it isn't reported with -dumpspecs.
Reading through some thread of the gcc mailing list I had the impression specs aren't liked by everyone (but if I'm not wrong 4.9 add another option --with-extra-specs) instead preferred way to do such customizations appears to be configure.host, but I'm done and not looking into it, have fun! :-)
see also: gcc faq rpath
update above
I don't know if you can set a pre-defined rpath, probably if you can would be in the linker ld of binutils not in gcc/g++, but why would you do that?
Just export LD_LIBRARY_PATH at runtime and LD_RUN_PATH at build time
export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
ldd a.out
ldd should show the paths you exported.
To quote a message given when a shared library is built with libtool:
If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following:
add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution
add LIBDIR to the `LD_RUN_PATH' environment variable during linking
use the `-Wl,--rpath -Wl,LIBDIR' linker flag
have your system administrator add LIBDIR to `/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
for completeness
the Makefile I used for testing the thing, all the configure options, environment variables (see boot ldflags) I tried didn't work, --enable-rpath included.
use with mkdir ~/gcc copy the Makefile below into ~/gcc then cd ~/gcc && make build-gcc
notice the options used are only for this test case, don't use as reference.
FETCH = aria2c --file-allocation=none -c -d dl
NICE = nice -n 19
PARALLEL = -j4
DESTDIR = $(HOME)/gcc/install
SRCDIR = $(HOME)/gcc/src
all:
# if more downloads are added just remove {dl,src}/*-my-stamp not the .bak
# the .bak should avoid to rebuild targets because of timestamp
touch_stamp = if [ -f $#.bak ]; then \
touch -r $#.bak $#; \
else \
touch $# $#.bak; \
fi
dl/dl-my-stamp:
$(FETCH) https://ftp.gnu.org/gnu/gcc/gcc-4.7.2/gcc-4.7.2.tar.bz2
$(FETCH) http://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2
$(FETCH) ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-0.8.1.tar.gz
$(FETCH) https://ftp.gnu.org/gnu/mpfr/mpfr-2.4.2.tar.bz2
$(FETCH) --check-certificate=false http://www.mirrorservice.org/sites/sourceware.org/pub/binutils/snapshots/binutils-2.24.51.tar.bz2 \
ftp://sourceware.org/pub/binutils/snapshots/binutils-2.24.51.tar.bz2
$(touch_stamp)
untar_dep = src/untar-my-stamp
src/untar-my-stamp: dl/dl-my-stamp
mkdir -p src
tar -C src -xjf dl/gcc-4.7.2.tar.bz2
tar -C src -xjf dl/gmp-4.3.2.tar.bz2
tar -C src -xzf dl/mpc-0.8.1.tar.gz
tar -C src -xjf dl/mpfr-2.4.2.tar.bz2
tar -C src -xjf dl/binutils-2.24.51.tar.bz2
$(touch_stamp)
define configure-rule
$(1)_install = $(DESTDIR)/$(1)-install-my-stamp
$(1)_builddir = $$($(1)_dir)/build
$(DESTDIR)/$(1)-install-my-stamp: $$($(1)_deps)
mkdir -p $$($(1)_builddir)
cd $$($(1)_builddir) && \
$$($(1)_env) ../configure --cache-file=$(SRCDIR)/$(1)-config.cache \
$$($(1)_configure)
$(NICE) make -C $$($(1)_builddir) $$($(1)_make_target) $(PARALLEL)
ifneq ($$($(1)_post_make),)
$$($(1)_post_make)
endif
touch $$#
.PHONY: build-$(1) clean-$(1)
build-$(1): $$($(1)_install)
clean-$(1):
-rm -fr $$($(1)_builddir)
endef
gmp_dir = src/gmp-4.3.2
gmp_env = CONFIG_SITE=$(SRCDIR)/config.site
gmp_configure = --prefix=$(DESTDIR) \
--disable-shared --enable-static --enable-cxx
gmp_deps = $(untar_dep)
gmp_make_target = install
$(eval $(call configure-rule,gmp))
mpfr_dir = src/mpfr-2.4.2
mpfr_env = CONFIG_SITE=$(SRCDIR)/config.site
mpfr_configure = --prefix=$(DESTDIR) \
--disable-shared --enable-static \
--with-gmp=$(DESTDIR)
mpfr_deps = $(untar_dep) $(gmp_install)
mpfr_make_target = install
$(eval $(call configure-rule,mpfr))
mpc_dir = src/mpc-0.8.1
mpc_env = CONFIG_SITE=$(SRCDIR)/config.site
mpc_configure = --prefix=$(DESTDIR) \
--disable-shared --enable-static \
--with-gmp=$(DESTDIR) --with-mpfr=$(DESTDIR)
mpc_deps = $(untar_dep) $(gmp_install) $(mpfr_install)
mpc_make_target = install
$(eval $(call configure-rule,mpc))
gcc_dir = src/gcc-4.7.2
gcc_env = CONFIG_SITE=$(SRCDIR)/config.site \
CFLAGS="-I/usr/include/i386-linux-gnu" \
CXXFLAGS="-I/usr/include/i386-linux-gnu"
gcc_configure = --prefix=$(DESTDIR) \
--libdir=$(DESTDIR)/lib \
--with-local-prefix=$(DESTDIR) \
--with-gmp=$(DESTDIR) --with-mpfr=$(DESTDIR) \
--with-mpc=$(DESTDIR) \
--disable-bootstrap \
--enable-languages=c,c++ \
--disable-libgomp --disable-multilib \
--disable-libmudflap --disable-libssp \
--disable-libquadmath \
--enable-rpath \
MAKEINFO=missing
gcc_deps = $(untar_dep) $(gmp_install) $(mpfr_install) $(mpc_install)
gcc_make_target =
gcc_post_make = make -C $(gcc_builddir) install
$(eval $(call configure-rule,gcc))
binutils_dir = src/binutils-2.24.51
#binutils_env = LDFLAGS=-Wl,-rpath\ $(DESTDIR)/lib
binutils_env = CONFIG_SITE=$(SRCDIR)/config.site \
CFLAGS="-I/usr/include/i386-linux-gnu" \
BOOT_LDFLAGS="-rpath-link=$(DESTDIR)/lib -rpath=$(DESTDIR)/lib"
binutils_configure = --prefix=$(DESTDIR) \
--libdir=$(DESTDIR)/lib \
--with-gmp=$(DESTDIR) \
--enable-rpath
binutils_deps = $(untar_dep) $(gmp_install)
#binutils_make_target = install
binutils_post_make = make -C $(binutils_builddir) install
$(eval $(call configure-rule,binutils))
.PHONY: env
env:
#echo export PATH=$(DESTDIR)/bin:\$$PATH
#echo export LIBRARY_PATH=/usr/lib/i386-linux-gnu
I was installing httpd-2.4.51 and needed to specify -rpath to compile the program. I use the linker flag -Wl,-rpath -Wl,LIBDIR.
Use commands:
sudo mv httpd.c /usr/lib #create a .c file and move it to the default directory for the library file
sudo gcc -o httpd httpd.c -L$--prefix=/usr/lib -lhttpd -Wl,-rpath=$--prefix=/usr/lib
Your can check where you have gcc installed:
whereis gcc
gcc: /usr/bin/gcc /usr/lib/gcc /usr/share/man/man1/gcc.1.gz

Why does this makefile only work with a single job?

I'm trying to write a Makefile which compiles a cross compiler.
It downloads GCC and binutils, extract the archive, run the configure script and run make.
This is the Makefile I wrote:
# Versions
GCC_VERSION := 6.3.0
BINUTILS_VERSION := 2.27
# Build
TARGET ?= i686-elf
PREFIX := $(realpath build)
# Phony tasks
.PHONY: all clean gcc binutils
# Targets
BINUTILS_TARGETS := build/bin/${TARGET}-addr2line build/bin/${TARGET}-ar \
build/bin/${TARGET}-as build/bin/${TARGET}-c++filt \
build/bin/${TARGET}-elfedit build/bin/${TARGET}-gprof \
build/bin/${TARGET}-ld build/bin/${TARGET}-ld.bfd build/bin/${TARGET}-nm \
build/bin/${TARGET}-objcopy build/bin/${TARGET}-objdump \
build/bin/${TARGET}-ranlib build/bin/${TARGET}-readelf \
build/bin/${TARGET}-size build/bin/${TARGET}-strings \
build/bin/${TARGET}-strip
GCC_TARGETS := build/bin/${TARGET}-cpp build/bin/${TARGET}-gcc \
build/bin/${TARGET}-gcc-${GCC_VERSION} build/bin/${TARGET}-gcc-ar \
build/bin/${TARGET}-gcc-nm build/bin/${TARGET}-gcc-ranlib \
build/bin/${TARGET}-gcov build/bin/${TARGET}-gcov-tool
# Aliases
all: binutils gcc
gcc: ${GCC_TARGETS}
binutils: ${BINUTILS_TARGETS}
# Download the packages
packages/gcc-${GCC_VERSION}.tar.bz2:
curl ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.bz2 \
-o $#
packages/binutils-${BINUTILS_VERSION}.tar.bz2:
curl ftp://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.bz2 \
-o $#
# Extract them
packages/gcc-${GCC_VERSION}/configure: packages/gcc-${GCC_VERSION}.tar.bz2
tar -xmjf $< -C packages
packages/binutils-${BINUTILS_VERSION}/configure: packages/binutils-${BINUTILS_VERSION}.tar.bz2
tar -xmjf $< -C packages
# Build them
${GCC_TARGETS}: packages/gcc-${GCC_VERSION}/configure
mkdir -p build/gcc
cd build/gcc && ../../packages/gcc-${GCC_VERSION}/configure \
--target=${TARGET} --prefix=${PREFIX} --disable-nls \
--enable-languages=c --without-headers && make all-gcc && \
make all-target-libgcc && make install-gcc && make install-target-libgcc
${BINUTILS_TARGETS}: packages/binutils-${BINUTILS_VERSION}/configure
mkdir -p build/binutils
cd build/binutils && ../../packages/binutils-${BINUTILS_VERSION}/configure \
--target=${TARGET} --prefix=${PREFIX} --with-sysroot --disable-nls \
--disable-werror && make && make install
# Clean everything
clean:
rm -rf build/*
rm -rf packages/*
It works when running make with no options, but when I use the jobs option, it fails (but not everytime): it download binutils and GCC in parallel.
When binutils is fully downloaded, it extracts it and compiles it, then the GCC download ends, but it doesn't do anything and there are no errors.
Also sometimes the compilation of GCC or binutils fails with strange errors (I will edit this post with some of them).
Not sure about the exact source of your specific build failures, but the Makefile is problematic: the 2 build rules have multiple targets. Make does not support this well, see here for an explanation.
Make with jobs fails because it starts multiple instances of the same recipe but these instances can't run together correctly.
${GCC_TARGETS}: packages/gcc-${GCC_VERSION}/configure
mkdir -p build/gcc
cd build/gcc && ../../packages/gcc-${GCC_VERSION}/configure ... make ...
This is trouble maker, I guess, because Make with jobs initiates multiple configure invocations in the same directory to run asynchronously. So you have multiple configure scripts running and adding bits to the same directory. And then multiple instances of Make are invoked in the same build directory. Perfect mess.
Something like:
${GCC_TARGETS}: packages/gcc-${GCC_VERSION}/configure
mkdir -p build/gcc/$(nodir $#) && cd build/gcc/$(nodir $#) ...
Should fix the problem by means of starting configure & make sequences in different directories. You need similar fix for ${BINUTILS_TARGETS} too.

Resources