using external libraries with msys - minGW - compilation

I want to write and compile C++ code that requires the FLTK 1.3.2 GUI libraries.
I would like to use minGW with MSYS.
I have installed minGW and MSYS properly and have been able to build FLTK with ./configure
make. Everything worked up to this point.
Now I am testing the hello program, and can get the compiler to locate the header files, but it returns errors - which I believe are a result of the compiler not finding the location of the FLTK library. I have looked over the minGW site and it seems the difficulty of getting MSYS to direct the compiler to the correct location is not uncommon.
I have worked with C++ minGW for about a year but am completely new to MSYS.
Here is my command:
c++ Hello.cxx -Lc:/fltk-1.3.2/test -Ic:/fltk-1.3.2 -o Hello.exe
(I am not sure if my syntax is correct so any comments are appreciated)
Here is what I get from the compiler:
C:\Users\CROCKE~1\AppData\Local\Temp\ccbpaWGj.o:hello.cxx(.text+0x3c): undefined reference to 'Fl_Window::Fl_Window(int, int, char const*)'
... more similar comments...
collect2: ld returned exit status
It seems the compiler can't find the function definitions which I believe are in c:/fltk-1.3.2/test.
Again, I am a newbie so any help is greatly appreciated.
Thanks.

Your compile command is not good... You only inform LD where to search for additional libraries with the -L parameter, but you do not specify any library you actually want to use. For that you use -l flag.
So the command should be something like: g++ Hello.cxx -Lc:/fltk-1.3.2/test -Ic:/fltk-1.3.2 -o Hello.exe -llibfltk_images -llibfltk -llibwsock32 -llibgdi32 -llibuuid -llibole32
My recommendation - use the provided fltk-config script to obtain the flags.
Here is a MinGW makefile I "stole" from here: http://www.fltk.org/articles.php?L1286 .
# Makefile for building simple FLTK programs
# using MinGW on the windows platform.
# I recommend setting C:\MinGW\bin AND C:\MinGW\msys\1.0\bin
# in the environment %PATH% variable on the development machine.
MINGW=C:/MinGW
MSYS=${MINGW}/msys/1.0
FLTK_CONFIG=${MSYS}/local/bin/fltk-config
INCLUDE=-I${MSYS}/local/include
LIBS=-L${MSYS}/local/lib
CC=${MINGW}/bin/g++.exe
RM=${MSYS}/bin/rm
LS=${MSYS}/bin/ls
EXE=dynamic_buttons_scroll.exe
SRC=$(shell ${LS} *.cxx)
OBJS=$(SRC:.cxx=.o)
CFLAGS=${INCLUDE} `${FLTK_CONFIG} --cxxflags`
LINK=${LIBS} `${FLTK_CONFIG} --ldflags`
all:${OBJS}
${CC} ${OBJS} ${LINK} -o ${EXE}
%.o: %.cxx
${CC} ${INCLUDE} ${CFLAGS} -c $*.cxx -o $*.o
clean:
- ${RM} ${EXE}
- ${RM} ${OBJS}
tidy: all
- ${RM} ${OBJS}
rebuild: clean all
# Remember, all indentations must be tabs... not spaces.

Related

REPAST HPC WSL Installation leads to boost no being found

When trying to run Repast HPC executables I get the following error:
./main.exe: error while loading shared libraries: libboost_mpi-mt.so.1.61.0: cannot open shared object file: No such file or directory ./main.exe: error while loading shared libraries: libboost_mpi-mt.so.1.61.0: cannot open shared object
In the make file I define the link to boost in an env file with the below:
BOOST_INCLUDE= -I$(HOME)/sfw/Boost/Boost_1.61/include/
BOOST_LIB_DIR= -L$(HOME)/sfw/Boost/Boost_1.61/lib/
This is linked to a make file with the following make file
include ./env
.PHONY: clean
clean:
rm -f *.o
rm -f *.exe
.PHONY: compile
compile:
$(MPICXX) $(BOOST_INCLUDE) -c Main.cpp -o Main.o
$(MPICXX) $(BOOST_LIB_DIR) -o main.exe Main.o $(BOOST_LIBS)
.PHONY: all
all: clean compile
Boost in tsnow#DESKTOP-IF7CEHL:~/sfw/Boost/Boost_1.61/lib$ so it should link well across.
Any help appreciated, just trying to get a tutorial running.
We typically don't link repast to boost, but rather use rpath to let the model executable know where the boost and repast libraries are. For example in your Makefile:
REPAST_LIB_DIR = $(REPAST_HOME)/lib
BOOST_LIB_DIR = $(HOME)/theta/sfw/boost-1.66.0/lib
RPATHS += -Wl,-rpath -Wl,$(REPAST_LIB_DIR) -Wl,-rpath -Wl,$(BOOST_LIB_DIR)
and then add $(RPATHS) after the list of libraries during linking.
model : $(EXEC_OBJECTS)
$(CXXLD) -fopenmp -dynamic $^ $(LIBS) $(RPATHS) -o $(NAME)
Some of those args might not be appropriate for WSL, but hopefully the RPATHS part makes sense.
So, if after your include directive, you add
RPATHS=-Wl,-rpath -Wl,$(BOOST_LIB_DIR)
and update the second line of your compile target with
$(MPICXX) $(BOOST_LIB_DIR) -o main.exe Main.o $(BOOST_LIBS) $(RPATHS)
The location of your boost libs is compiled into main.exe, and it should find it.
The command:
export LD_LIBRARY_PATH=/home/tsnow/sfw/Boost/Boost_1.61/lib/
allowed boost to be found.

arm-none-eabi-ld cannot find -mcpu=cortex-m3

There is another question with similar naming but it was never resolved.
I installed arm-none-eabi gcc and binutils from the GNU Arm Embedded PPA on Ubuntu. This toolchain normally works fine.
Today however, in my Makefile, I link with -march=armv7-m -mcpu=cortex-m3 as some of the options. This immediately causes ld to fail like this:
$ arm-none-eabi-ld -mcpu=cortex-m3 -march=armv7-m -Tcm3.ld # and some more options
arm-none-eabi-ld: unrecognised emulation mode: arch=armv7-m
Supported emulations: armelf
What have I done wrong? I can't seem to find any information about this!
I've also tested this with my other toolchain (CodeSourcery, March 2011). That toolchain normally works, but fails now too.
Should I be linking with gcc not ld?
It appears that linking with gcc rather than ld solves the problem. I can even pass in the linker script without having to use -Wl,-T.
I'm still open as to why ld didn't work in the first place.

Instruct CMake to use CXX and CXXFLAGS when driving link?

We are catching link errors on Solaris with makefiles generated by CMake 3.6.2. In the testing below, we are using GCC and not SunCC. From the looks of it, CMake is applying our options inconsistently:
Typical compile command
[ 2%] Building CXX object CMakeFiles/cryptopp-object.dir/cpu.cpp.o
/bin/c++ -fPIC -march=native -m64 -Wa,--divide -o CMakeFiles/cryptopp-object.dir/cryptlib.cpp.o
-c /export/home/jwalton/cryptopp/cpu.cpp
Abbreviated link command
/bin/c++ CMakeFiles/cryptest.dir/bench1.cpp.o CMakeFiles/cryptest.dir/bench2.cpp.o
...
CMakeFiles/cryptest.dir/fipstest.cpp.o -o cryptest.exe libcryptopp.a -lnsl -lsocket
Typical link error
ld: fatal: file CMakeFiles/cryptopp-object.dir/cryptlib.cpp.o: wrong ELF class: ELFCLASS64
Notice the file was compiled with -march=native -m64 (its a 64-bit capable machine and kernel), but the link invocation is missing it (the default is 32-bit on Solaris).
Attempting to search for "cmake use CXXFLAGS link" is producing too much irrelevant noise, and I'm not having much luck finding the CMakeList.txt option. I also want to avoid duplicating the work into LDFLAGS, or performing the work of reformatting the options (CXXFLAGS option -Wl,-x becomes LDFLAGS option -x).
How do I instruct CMake to use both CXX and CXXFLAGS when driving link?
I found Running a different program for the linker on the CMake users mailing list, but it does not feel right to me (also, the problem and context are slightly different). It also does not work.
Here is a small example:
PROJECT(foo)
SET(CMAKE_CXX_LINK_EXECUTABLE
"purify <CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
ADD_EXECUTABLE(foo foo.cxx)
I also found Setting global link flags on the mailing list. It does not work, either.
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_CXX_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_FLAGS}")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_CXX_FLAGS}")

Makefile library prerequisite

I have a makefile, which I am using to cross-compile for and embeded ARM platform with gcc. Specifcally, I am using arm-none-eabi-gcc, but the same appiles to avr-gcc, msp430-gcc, etc. Typically when using make+gcc (and not cross compiling) I list libs as prerequisite as follows:
programA.elf: programA.o foo.o -lm ...etc
programB.elf: programB.o bar.o -lftdi ...etc
%.elf:
gcc $(LDFLAGS) -o $# $^
Make handles this "-lsyntax" very nicely, and its very convienient if you are building multiple progams/targets and want to have a generic rule for linking. The problem I have run into durring cross-compiling is that arm-none-eabi-gcc obviously has a different libm.a than my system's gcc libm.so (for example), but Make doesn't know whats going on here and keeps trying to use the x86 libm instead of the ARM base one. I can get things to work by adding the line:
.LIBPATTERNS = /usr/lib/arm-none-eabi/newlib/lib%.a
but it seems kinda clunky and exposes anyone wanting to compile the project to knowing a little more about the toolchain's install locations than is normally expected.
My question is: "Is there a better convention to list a binary's lib dependencies I should be using here that wont break when cross-compiling?"
This can be done. But a general solution is complex. I have Makefiles which build arm, x86, and c67 executables from a single set of sources. The page you reference eludes to the key: VPATH. I suggest a separate subdirectory for each architecture. The following is not working code, but it gives the idea
all: arm/pgma x86/pgma
vpath %.c $(CURDIR)
arm x86:
mkdir -p $#
arm/pgma: arm/main.o arm/sub.o | arm
x86/pgma: x86/main.o x86/sub.o more.o | x86
arm/%: CC=arm-none-eabi-gcc
arm/%: CFLAGS += -march=armv7-a -mtune=corex-a8
x86/%: CC=gcc
arm/%: VPATH = /usr/lib/arm-none-eabi/newlib
# Notice, VPATH not needed for x86 since it is the native host
This entire concept can be extend to build dependency file is each subdirectory as well debug and release variants. I have not tried this with the -lfoo, but it should work. E.g.,
arm/pgma: arm/main.o arm/sub.o -lmylib | arm

Cross-Compiling for an embedded ARM-based Linux system

I try to compile some C code for an embedded (custom) ARM-based Linux system. I set up an Ubuntu VM with a cross-compiler named arm-linux-gnueabi-gcc-4.4 because it looked like what I needed. Now when I compile my code with this gcc, it produces a binary like this:
$ file test1
test1: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.31,
BuildID[sha1]=0x51b8d560584735be87adbfb60008d33b11fe5f07, not stripped
When I try to run this binary on the embedded Linux, I get
$ ./test1
-sh: ./test1: not found
Permissions are sufficient. I can only imagine that something's wrong with the binary format, so I looked at some working binary as reference:
$ file referenceBinary
referenceBinary: ELF 32-bit LSB executable, ARM, version 1, dynamically linked
(uses shared libs), stripped
I see that there are some differences, but I do not have the knowledge to derive what exactly I need to fix and how I can fix that. Can someone explain which difference is critical?
Another thing I looked at are the dependencies:
$ ldd test1
libc.so.6 => not found (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
(Interestingly, this works on the target system although it cannot execute the binary.) The embedded system only has a libc.so.0 available. I guess I need to tell the compiler the libc version I want to link against, but as I understand it, gcc just links against the version it comes with, is this correct? What can I do about it?
Edit: Here's the Makefile I use:
CC=/usr/bin/arm-linux-gnueabi-gcc-4.4
STRIP=/usr/bin/arm-linux-gnueabi-strip
CFLAGS=-I/usr/arm-linux-gnueabi/include
LDFLAGS=-nostdlib
LDLIBS=../libc.so.0
SRCS=test1.c
OBJS=$(subst .c,.o,$(SRCS))
all: test1
test1: $(OBJS)
$(CC) $(LDFLAGS) -o main $(OBJS) $(LDLIBS)
$(STRIP) main
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
clean:
rm -f $(OBJS)
include .depend
What you should probably do is to install libc6 on the embedded system. Read this thread about a similar problem. The solution in post #5 was to install:
libc6_2.3.6.ds1-13etch9_arm.deb
linux-kernel-headers_2.6.18-7_arm.deb
libc6-dev_2.3.6.ds1-13etch9_arm.deb
Your other option is to get the libc from the embedded system onto your VM and then pass it to the gcc linker and use the -static option.
This solution was also mentioned in the above thread. Read more about static linking here.
Other things to try:
In this thread they suggest removing the -mabi=apcs-gnu flag from your makefile if you're using one.
This article suggests feedint gcc the -nostdlib flag if you're compiling from the command line.
Or you could switch to using the arm-none-eabi-gcc compiler. References on this can be found here and here.

Resources