I'm trying to build my own library. It worked on x86 linux so I wanna build for MIPS Linux (Little endian.)
I'm using sourcery codebench in Mento Graphics and buildroot and CMake.
I configured build_all.sh like below.
#!/bin/bash -ev
export TARGETROOT="/usr/mipsel-buildroot-linux-gnu/sysroot"
mkdir -p mips_build
cd mips_build
cmake -DCMAKE_SYSTEM_NAME="Linux" \
-DCMAKE_C_COMPILER="${CROSS_COMPILE}gcc" \
-DCMAKE_CXX_COMPILER="${CROSS_COMPILE}g++" \
-DCMAKE_AR="${CROSS_COMPILE}ar" \
-DCMAKE_C_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
-DCMAKE_CXX_FLAGS="-EL -c -g -O2 -fPIC --sysroot=$TARGETROOT " \
../
make
cd ..
Where $CROSS_COMPILE=/home/vagrant/bd1/mips-2014.05/bin/mips-linux-gnu-
And CMakeFiles.txt is like below.
make_minimum_required (VERSION 2.6)
set(EMSG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../src/eagle_msg/include )
set(EMSG_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib )
set (PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (PROJECT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set (PROJECT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(LIBRARIES
libemsg.a
libzmq.a
libprotobuf.a
libprotobuf-c.a
libpthread.a
libstdc++.a
)
#For controller : Client
SET(EXECUTABLE test_controller)
project (${EXECUTABLE})
include_directories(
${PROJECT_INCLUDE_DIR}
${EMSG_INCLUDE_DIR}
$ENV{TARGETROOT}/usr/include
)
link_directories(
${PROJECT_LIB_DIR}
${EMSG_LIB_DIR}
$ENV{TARGETROOT}/usr/lib
)
set(SRCS
test_controller.cpp
)
add_executable( ${EXECUTABLE} ${SRCS})
target_link_libraries( ${EXECUTABLE} ${LIBRARIES} )
Then it makes the error like below.
[ 40%] Built target emsg
Linking CXX executable ../../../bin/test_controller
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make[2]: *** [../bin/test_controller] Error 1
make[1]: *** [test/emsg_test/CMakeFiles/test_controller.dir/all] Error 2
So I checked the format of libstdc++.so. Then it's ELF 32-bit LSB shared object, MIPS, MIPS32. That's the right version. Then what can I do to solve?
/usr/mipsel-buildroot-linux-gnu/sysroot# file /usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.*
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.a: current ar archive
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6: symbolic link to `libstdc++.so.6.0.19'
/usr/mipsel-buildroot-linux-gnu/sysroot/usr/lib/libstdc++.so.6.0.19: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, with unknown capability 0xf41 = 0x756e6700, not stripped
New information
It seems to be the problem of buildroot. I checked the sysroot value of mips-linux-gnu-gcc.
This is the result before installing buildroot.
$ mips-linux-gnu-gcc --print-sysroot
/home/vagrant/bd1/mips-2014.05/bin/../mips-linux-gnu/libc
This is the result after installing buildroot.
$ mips-linux-gnu-gcc --print-sysroot
/usr/usr/mipsel-buildroot-linux-gnu/sysroot/soft-float/el
I also found the post about similar problem. But it's old issue.
Please use the CMake toolchain file provided by Buildroot. It is generated in $(HOST_DIR)/usr/share/buildroot/toolchainfile.cmake. Use it this way:
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/host/usr/share/buildroot/toolchainfile.cmake
And then you can remove all your other -DCMAKE_ variable, since the toolchain file indicates to CMake which compiler to use, which flags, etc.
I found the reason. The main reason is sysroot path. Buildroot organizes all toolchain into $BUILDROOT/output/host/. So you should change the PATH environment like below.
HOST_BINARY="$BUILDROOT/output/host/usr/bin"
PATH="${PATH}:${HOST_BINARY}"
Where $BUILDROOT is the folder where buildroot is extracted.
You should use toolchain below $BUILDROOT/output/host/usr/bin.
Related
I would like to generate MIPS binaries using gcc on an x86 machine. In order to install MIPS cross-compiler I followed the directions on this page. I could install gcc and binutils successfully. I tried to to compile a simple hello world program using the cross compiler.
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 hi.c
I got the following error.
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crt1.o: No such file or directory
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crti.o: No such file or directory
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find -lc
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crtn.o: No such file or directory
collect2: error: ld returned 1 exit status
I did some research online to figure out what the problem was, and changed the command I used to the following.
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -B/usr/lib/i386-linux-gnu -mips1 hi.c
Now I get this error message:
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: /usr/lib/i386-linux-gnu/crt1.o: Relocations in generic ELF (EM: 3)
/usr/lib/i386-linux-gnu/crt1.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
I am not sure what the problem is. The only thing I can think of is the "--without-headers" option passed to configure program when building gcc. Configure command for gcc given on the linux-mips page is as below.
% ../gcc-3.8.2/configure --target=$TARGET --prefix=$PREFIX \
--enable-languages=c --without-headers \
--with-gnu-ld --with-gnu-as \
--disable-shared --disable-threads \
--disable-libmudflap --disable-libgomp \
--disable-libssp --disable-libquadmath \
--disable-libatomic
I would appreciate some help. The system on which I generated the cross compiler uses gcc4.7.2-5. I used the sources for gcc-4.8.2 and binutils-2.24 to generate the cross compiler.
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 hi.c
Add a SYSROOT to the compile command. It should look similar to:
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 --sysroot=/opt/cross/... hi.c
The SYSROOT will provide the header and library path automatically (rather than adding -I and -L individually).
You will know when you have a SYSROOT because there will be a bin/, include/ and lib/ in the path used. For example, here's a SYSROOT for arm-linux-gnueabi (i.e., arm-linux-gnueabi-gcc and arm-linux-gnueabi-g++):
$ ls /usr/arm-linux-gnueabi
bin include lib
So, in this example, you would use --sysroot=/usr/arm-linux-gnueabi.
If you need help with locating a SYSROOT, then perform a find:
$ find /usr -name crt1.o
/usr/arm-linux-gnueabi/lib/crt1.o
/usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o
/usr/lib/x86_64-linux-gnu/crt1.o
In your case, you would probably search from /opt/cross. Obviously, you would want the one for the target (arm-linux-gnueabi), and not the ones for the host (x86_64-linux-gnu).
Adding --sysroot= would resolve this issue.
As you are cross-compiling you shouldn't select just any other folder which has crt1.o or crtX.o as your sysroot directory. It could be your host-machine's files. (Which if you are running on a x86, it would be for x86). Again it varies from 32bit and 64bit.
With newer version's of GCC toolchain, you need to have a sdk part of it which has the appropriate sysroot and crt1.o. This should go with your ABI and your target architecture.
I have problem with building aplication with opencv library for ARM.
I installed Opencv 2.4.6.1 for my pc with helping this a tutorial http://docs.opencv.org/doc/tutorials/introduction/linux_install/linux_install.html#linux-installation
After that i try build example for my pc:
gcc main.c -o main ´pkg-config --libs --clags opencv´ -lpthread
It works.
Next, i install arm-linux-gnueabihf-gcc, wrote example and tryied it. It works.
now i make opencv library for ARM
cd /opt/opencv-2.4.6.1/platforms/linux
mkdir build_hardfp
pico arm-gnueabi.toolchain.cmake
change 4.6 to 4.7.2
cd build_hardfp
cmake -DCMAKE_TOOLCHAIN_FILE=../arm-gnueabi.toolchain.cmake -DWITH_TBB=OFF -DWITH_QT=OFF -D SOFTFP=OFF -D WITH_V4L=ON -D WITH_OPENGL=ON –D CMAKE_BUILD_TYPE=RELEASE –D BUILD_SHARED_LIBS=OFF -D CMAKE_INSTALL_PREFIX=/opt/opencv-2.4.6.1/rpi ../../..
make
make install
And now my problem:
I try build my example
arm-linux-gnueabihf-gcc -o main main.c -lpthread -I/opt/opencv-2.4.6.1/rpi/include -I/opt/opencv-2.4.6.1/rpi/include/opencv -I/opt/opencv-2.4.6.1/rpi/lib -L/opt/opencv-2.4.6.1/rpi/ -lcv -lhighgui
main.c: In function ‘main’:
main.c:12:8: warning: assignment makes pointer from integer without a cast [enabled by default]
/home/honza/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcv
/home/honza/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lhighgui
collect2: error: ld returned 1 exit status
Probably i must have all the dependencies compile for ARM architecture. I think, i took care of this in previous steps, with using cmake.
Maybe i didn't set paths.
What am I doing wrong and how to fix it?
You use old names for OpenCV libraries : -lcv -lhighgui. OpenCV has new structure from 2.0 version. Use this flags : -lopencv_core -lopencv_highgui.
getting following error with the command g++ -o test -L . -l pq
libpq.so: file not recognized: File format not recognized
#file libpq.so
libpq.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), not stripped
gcc version 4.1.2 20070115 (SUSE Linux)
I am getting the same error if I try to use -l dbodbc instead of -l pq.
Note that test.c is a simple hello world program.
Thanks in Advance.
file /usr/bin/g++ tells you that g++ itself is a 64-bit executable, i.e. it runs on a 64-bit machine, it doesn't tell you that g++ can compile 64-bit code (it's very unlikely but it could be a cross compiler for a completely different processor!) Use g++ -v or g++ -dumpmachine to find out what target it generates executables for.
G++ doesn't actually use that library, it just passes the -l option to the linker, so the error is coming from the linker, ld
If ld and objdump are both saying they can't recognize the library but the same file is fine on a different machine, I would try updating or reinstalling the binutils package, which provides both ld and objdump.
You might have a 32-bit binutils installed, so its ld and objdump wouldn't understand the x86_64 library. Ensure you have the 64-bit (i.e. x86_64) binutils RPM installed.
I am able to make a shared library without problems. I create libcbitcoin.so (without any errors) and attempt to link against it with an executable as well as OpenSSL libraries. I use this command:
gcc -L/media/sf_BitEagle_Projects/cbitcoin/build/bin -lcbitcoin \
-Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin -lssl -lcrypto \
-L/usr/local/ssl/lib/ -o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o
The bin directory is the location of the library. The obj directory has the object files I wish to link into an executable. In the command I use the -L, -l and -rpath* options which I thought was all that is needed for linking in Linux. It seems I am wrong since I get errors like:
/media/sf_BitEagle_Projects/cbitcoin/test/testCBAddress.c:40:
undefined reference to `CBNewByteArrayFromString'
CBNewByteArrayFromString is found in the library. For some reason it is not being linked. OpenSSL too:
/media/sf_BitEagle_Projects/cbitcoin/dependencies/crypto/CBOpenSSLCrypto.c:37:
undefined reference to `SHA1'
How do I get the linking to work?
GCC version: gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
It is on Linux Mint 13 (Maya).
Put the libraries after the object files on the link command line:
gcc /media/sf_BitEagle_Projects/cbitcoin/build/obj/testCBAddress.o \
/media/sf_BitEagle_Projects/cbitcoin/build/obj/CBOpenSSLCrypto.o \
-L/media/sf_BitEagle_Projects/cbitcoin/build/bin \
-lcbitcoin -Wl-rpath,/media/sf_BitEagle_Projects/cbitcoin/build/bin \
-L/usr/local/ssl/lib/ -lssl -lcrypto \
-o /media/sf_BitEagle_Projects/cbitcoin/build/bin/testCBAddress
If you don't do that, the linker may decide that it needs nothing from a particular library at the stage of the link where it scans the library, and then it won't rescan the library later after it finds some undefined symbols in the object files. If you put the object files first, you don't run into this problem.
I think it is caused by can not find symbol. GCC will first go through from the left and will try to put the library file at the end.
I trying to get a cmake build system working on linux. The project contains a bunch of executables and two libraries. One of the executables is first built as a library, then that library is linked with the object file containing the man subroutine. This was done because the rest of the executables depend on that library. The tricky part is that the main subroutine is defined inside a module that the rest of sources depend on so this needs to be compiled before the rest of the sources. The effect is that the main subroutine gets added to the resulting library. This seems to work fine on Mac OS X but, the linking state fails on Linux.
The cmake file for the failing part looks like
cmake_minimum_required (VERSION 2.8)
# Create an empty variable to hold all the source files.
set (vmec_sources "")
# Add subdirectory for all the sources.
add_subdirectory (Sources)
add_library (vmec STATIC ${vmec_sources})
add_dependencies (vmec stell)
# Define an executable and link all libraries.
add_executable (xvmec ${CMAKE_CURRENT_SOURCE_DIR}/Sources/General/vmec_main.f)
add_dependencies (xvmec vmec)
target_link_libraries (xvmec vmec stell)
if ((NOT ${NETCDF_C} STREQUAL "") AND (NOT ${NETCDF_F} STREQUAL ""))
target_link_libraries (xvmec ${NETCDF_C} ${NETCDF_F})
endif ()
When running cmake, everything configures fine and generates a make file when I run make Mac OS X everything works fine. When I run make on Linux it fails.
The output from the make VERBOSE=1 On Linux produces
Linking Fortran executable ../build/bin/xvmec
cd /home/user/reconstruction/VMEC2000 && /usr/bin/cmake -E cmake_link_script CMakeFiles/xvmec.dir/link.txt --verbose=1
/usr/bin/gfortran -cpp -D NETCDF -I /usr/include CMakeFiles/xvmec.dir/Sources/General/vmec_main.f.o -o ../build/bin/xvmec -rdynamic ../build/lib/libvmec.a ../build/lib/libstell.a /usr/lib/libnetcdf.so /usr/lib/libnetcdff.so
/usr/lib/gcc/x86_64-linux-gnu/4.4.3/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status
make[2]: *** [build/bin/xvmec] Error 1
make[2]: Leaving directory `/home/user/reconstruction'
make[1]: *** [VMEC2000/CMakeFiles/xvmec.dir/all] Error 2
make[1]: Leaving directory `/home/user/reconstruction'
make: *** [all] Error 2
On Mac OS X, I get
Linking Fortran executable ../build/bin/xvmec
cd /Users/user/repo/trunk/VMEC2000 && "/Applications/CMake 2.8-8.app/Contents/bin/cmake" -E cmake_link_script CMakeFiles/xvmec.dir/link.txt --verbose=1
/usr/local/bin/gfortran -framework Accelerate -cpp -D DARWIN -D NETCDF -I /Users/user/NetCDF/include -O3 -ftree-vectorize -m64 -march=native -fomit-frame-pointer -falign-functions -mfpmath=sse CMakeFiles/xvmec.dir/Sources/General/vmec_main.f.o -o ../build/bin/xvmec ../build/lib/libvmec.a ../build/lib/libstell.a /Users/user/NetCDF/lib/libnetcdf.dylib /Users/user/NetCDF/lib/libnetcdff.dylib
"/Applications/CMake 2.8-8.app/Contents/bin/cmake" -E cmake_progress_report /Users/user/repo/trunk/CMakeFiles 100
[100%] Built target xvmec
The link line looks like it is linking all the same stuff in the correct order so I don't understand why this is failing on Linux.
Turns out I had the wrong file listed as containing the main method. It seems that later versions of gfortran can link 'MAIN__' from a inside a library while gfortran-4.4 cannot.