I am trying to compile a project in my system using qmake. Some dependencies of the project are not installed but reside in my home directory, more or less like this: libs files: /home/myusername/local/lib and my includes directory /home/myusername/local/include. Inside the include directory I have a folder, qjson with the needed headers from the library. In the lib folder I have the files libqjson.so libqjson.so.0 libqjson.so.0.7.1.
My qmake project file looks something like this:
linux-g++ {
INCLUDEPATH += /home/myusername/local/include/
LIBS += -L/home/myusername/local/lib/ -lqjson
}
and the generated makefile will produce commands like this one:
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB \
-DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I../qbuzz \
-I/usr/include/qt4/QtCore -I/usr/include/qt4/QtNetwork -I/usr/include/qt4/QtGui \
-I/usr/include/qt4 -I/home/myusername/local/include/ -I. -I. -I../myproject -I. \
-o qbuzz-result.o ../myproject/myfile.cc
It is clear that my include directory is in the -I option of gcc. myfile.cc contains an include like this one:
#include <qjson/parser.h>
However, after running make, I get the error:
../myproject/myfile.cc:2:26: fatal error: qjson/parser.h: No such file or directory
compilation terminated.
Now, if I modify the environment variable CPLUS_INCLUDE_PATH to add my local include file, I have no problems there, but in the linker stage I got the error:
/usr/bin/ld: cannot find -lqjson
collect2: ld returned 1 exit status
Even though the linker command was:
g++ -omyprogram main.o mainwindow.o myfile.o moc_mainwindow.o -L/usr/lib \
-L/home/myusername/local/lib/ -lqjson -lQtGui -lQtNetwork -lQtCore -lpthread
I also can get around modifying the environment variable LIBRARY_PATH. However I am looking for a solution that relies on modifying as few environment variables as possible, and after all, why are the options -L and -I there?
I works on Windows without problems using MinGW g++.
I notice that the QT's automatic include paths have no trailing slashes, and yours do. Have you tried writing the paths without trailing slashes?
linux-g++ {
INCLUDEPATH += /home/myusername/local/include
LIBS += -L/home/myusername/local/lib -lqjson
}
G++ and friends (i.e. as, ld, etc) will not directly tell you exactly where it looks for header and library files. One way to debug this is to run strace -o output.txt -eopen -s 1024 -f qmake. This will run qmake logging all open system calls of qmake and all of the child processes it forks. You will then be able to see in what directories and in what order it searches for header files (and libraries). Example output extract for stdio.h:
26069 open("/usr/lib/gcc/x86_64-redhat-linux/4.6.0/include/stdio.h", O_RDONLY|O_NOCTTY) = -1 ENOENT (No such file or directory)
26069 open("/usr/local/include/stdio.h", O_RDONLY|O_NOCTTY) = -1 ENOENT (No such file or directory)
26069 open("/usr/include/stdio.h", O_RDONLY|O_NOCTTY) = 4
Related
I'm trying to compile the simavr project from https://github.com/buserror/simavr on Windows 10 using MSYS2 and mingw-w64.
After editing the makefiles to enable the MSYS clauses (Which are commented out by default), and changing the order of 2 include files, I can get the project to compile. I do however encounter an error in the linking step.
The output is
C:/Programs/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/5.3.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lsimavr
Editing the makefile to print the ${LDFLAGS}, yield the following.
-L/lib -L/local/lib -L/c/Users/University/GitHub/simavr/simavr/../simavr/obj-i686-w64-mingw32 -lsimavr -lelf -lws2_32
Looking in the folder "obj-i686-w64-mingw32" mentioned in the build script, the file "libsimavr.a" is present. If I copy the file to the msys lib folder the linking step works fine.
The folder structure of the project is as follows:
simavr root (Where i run the makefile from, located in /c/Users/University/GitHub)
simavr
obj-i686-w64-mingw32
As far as I can tell, LD should be able to link properly without me copying the file manually. What am I missing here?
Edit:
The final command before the linker error.
cc -MMD -Werror -O2 -Wall -g -I/usr/local/include -DNO_COLOR -o obj-i686-w64-mingw32/run_avr.elf obj-i686-w64-mingw32/run_avr.o -L/lib -L/local/lib -L/c/Users/University/GitHub/simavr/simavr/../simavr/obj-i686-w64-mingw32 -lsimavr -lelf -lws2_32
Edit 2:
Cleaning the include paths of MSYS folders:
cc -MMD -Werror -O2 -Wall -g -DNO_COLOR -o obj-i686-w64-mingw32/run_avr.elf obj-i686-w64-mingw32/run_avr.o -L/c/Users/University/GitHub/simavr/simavr/../simavr/obj-i686-w64-mingw32 -lsimavr -lelf -lws2_32
C:/Programs/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/5.3.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lsimavr
Passing CC=gcc to make:
gcc -MMD -Werror -O2 -Wall -g -DNO_COLOR -o obj-i686-w64-mingw32/run_avr.elf obj-i686-w64-mingw32/run_avr.o -L/c/Users/University/GitHub/simavr/simavr/../simavr/obj-i686-w64-mingw32 -lsimavr -lelf -lws2_32
C:/Programs/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/5.3.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lsimavr
Edit 3:
Output of the find command:
$ find /c/Users/University/GitHub/simavr -name 'libsimavr.a'
/c/Users/University/GitHub/simavr/simavr/obj-i686-w64-mingw32/libsimavr.a
Note that previous entries have been made using the git bash prompt, not the one from msys2. However, running the same commands in the msys2 prompt or the mingw prompt from msys2 yields the same results.
Using mingw-w64 toolchain to build project you MUST remove from CFLAGS/CXXFLAGS/CPPFLAGS all paths with /usr, /local, /lib, /include as this paths can contain headers and libs from MSYS2 itself. Second, try pass "CC=gcc" to makefile.
I want to compile a C source file from command prompt that draws a triangle using openGL. I have the gcc compiler installed. The source file that I want to compile and execute is binded with something called Makefile.win32 file.
In my computer's F: drive there is a folder called opengl_codes. Inside that folder there are a bunch of files and two folders called hello_triangle and common.
Inside the hello_triangle folder I have these files : main.c and Makefile.win32.
I read a bunch of tutorials in the internet about Makefile, found out that to compile and execute the c source file I have to do this :-
1.first execute make -f Makefile.win32 in command prompt from the containing directory.
2.then compile the source file. i.e. gcc -o main.exe main.c
But when I execute the first command i.e. make -f Makefile.win32I get this error :-
gcc -Wall -pedantic -o hellot.exe main.c -I ../common/include ../common/win32/libglew32.dll.a ../common/win32/glfw3dll.a -lOpenGL32 -L ./ -lglew32 -lglfw3 -lm
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lglew32
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lglfw3
collect2.exe: error: ld returned 1 exit status
make: *** [all] Error 1
I am not understanding what is causing this error.
Makefile :-
BIN = hellot.exe
CC = gcc
FLAGS = -Wall -pedantic
INC = -I ../common/include
LOC_LIB = ../common/win32/libglew32.dll.a ../common/win32/glfw3dll.a
SYS_LIB = -lOpenGL32 -L ./ -lglew32 -lglfw3 -lm
SRC = main.c
all:
${CC} ${FLAGS} -o ${BIN} ${SRC} ${INC} ${LOC_LIB} ${SYS_LIB}
I compiled qt 4.8.5 for CentOS 6.4. Everything works perfectly. When I am compiling other libraries using this compiled qt version is compiling as long as I keep the installer folder in the same location. If I move the installer folder in another location, then I get the following errors:
cd common/ && make -f Makefile
make[1]: Entering directory `/path/MashLab/meshlab/src/common'
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -fPIC -DGLEW_STATIC -DQT_NO_DEBUG -DQT_SCRIPT_LIB -DQT_XMLPATTERNS_LIB -DQT_XML_LIB -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../../../qt/install_dir/mkspecs/linux-g++-64 -I. -I/path/qt/install/include/QtCore -I/path/qt/install/include/QtGui -I/path/qt/install/include/QtOpenGL -I/path/qt/install/include/QtXml -I/path/qt/install/include/QtXmlPatterns -I/path/qt/install/include/QtScript -I/path/qt/install/include -I../.. -I../../../vcglib -I../external/glew-1.7.0/include -I. -I../external/jhead-2.95 -I/usr/X11R6/inc
lude -I. -o filterparameter.o filterparameter.cpp
filterparameter.cpp:24:18: error: QtCore: No such file or directory
filterparameter.cpp:25:16: error: QMap: No such file or directory
filterparameter.cpp:26:17: error: QPair: No such file or directory
filterparameter.cpp:27:19: error: QAction: No such file or directory
It's still searching for the libs and includes in the path where it was installed even if I export the environment variables to the new location:
$: export QMAKESPEC=/path/qt/install_dir/mkspecs/linux-g++-64
$: export QTLIB=/path/qt/install_dir/lib
$: export QTINC=/path/qt/install_dir/include
$: export QTDIR=/path/qt/install_dir
installed location: /path/qt/install
new location: /path/qt/install_dir
Question: Is there a way (some arguments) which you can compile qt and use dynamic paths of libs/includes?
With Qt >= 5.3 create a qt.conf next to where qmake is (e.g. /path/qt/install_dir/bin/qt.conf)
[Paths]
Prefix = ..
If this doesn't work, check which at path qmake is looking for qt.conf with
strace qmake -query 2>&1 | grep qt.conf
I am trying to use a arm-none-eabi-gcc to compile some mbed code offline and ran into trouble when I tried to move the mbed folder outside the directory. The command that comes out of the make file is
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -T../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/MKL25Z4.ld -L./mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM -o Example.elf main.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/retarget.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/board.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/cmsis_nvic.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/mbed_overrides.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/system_MKL25Z4.o ../libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/startup_MKL25Z4.o -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
The folder named mbed contains all the headers and .o files required for basic mbed programming. However, when I try to move the mbed folder to a different folder and address it relatively, I get an error saying:
cannot find -l../libraries/mbed
Is it wrong to give relative paths to the -l option? If yes, how do I work around this problem?
Use the -L option to gcc to indicate where libraries are to be looked for. See the manual:
The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
The directories searched include several standard system directories plus any that you specify with -L.
I was able to get this working. The problem was that -L was not taking in relative paths. The new command looks something like this:
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -Wl,--gc-sections --specs=nano.specs -u _printf_float -u _scanf_float -T/<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/MKL25Z4.ld -o Example.elf main.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/retarget.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/board.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/cmsis_nvic.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/mbed_overrides.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/system_MKL25Z4.o /<path-to-folder>/workspace/mbed/libraries//mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM/startup_MKL25Z4.o -L/<path-to-folder>/workspace/mbed/libraries/mbed/TARGET_KL25Z/TOOLCHAIN_GCC_ARM -L/<path-to-folder>/workspace/mbed/libraries/mbed -lmbed -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
I'm not exactly sure why the relative path didn't work. One of my friends suggested that it may be because '..' is a symbolic link in some sense.
[SOLVED] created symlinks from /usr/lib/lib/* to /usr/lib*
[UPDATE 3] NEW VERSION:
Ok, I think I fixed something
use find / -name "libboost_system.*"
outout was
/usr/include/boost/lib/libboost_system.so
/usr/include/boost/lib/libboost_system.a
/usr/include/boost/lib/libboost_system.so.1.46.1
/usr/lib/lib/libboost_system.so
/usr/lib/lib/libboost_system.a
/usr/lib/lib/libboost_system.so.1.46.1
/usr/local/include/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/link-static/threading-multi/libboost_system.a
/usr/local/include/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/threading-multi/libboost_system.so.1.46.1
/usr/local/lib/libboost_system.so
/usr/local/lib/libboost_system.a
/usr/local/lib/libboost_system.so.1.46.1
/root/tmp/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/link-static/threading-multi/libboost_system.a
/root/tmp/boost_1_46_1/bin.v2/libs/system/build/gcc-4.4.3/release/threading-multi/libboost_system.so.1.46.1
why are these files in /usr/lib/lib ? and is it a problem ?
and the ls -l /usr/lib/lib | grep boost_system
ls -l /usr/lib/lib | grep boost_system
-rw-r--r-- 1 root root 21574 2011-05-09 15:15 libboost_system.a
lrwxrwxrwx 1 root root 25 2011-05-09 15:15 libboost_system.so -> libboost_system.so.1.46.1
-rwxr-xr-x 1 root root 20053 2011-05-09 15:15 libboost_system.so.1.46.1
atm my makefile looks like
LIBPATH=-I/usr/local/include/cpp-netlib
LIBS=$(LIBPATH) -lboost_system -lboost_filesystem -lboost_thread -lpthread
LD=g++ -g
CPP=g++ -c -g $(LIBS)
P=.
OBJ=$(P)/tmp/main.o $(P)/tmp/CLink.o $(P)/tmp/CFetcher.o
main: $(OBJ); $(LD) $(OBJ) $(LIBS) -o $#
$(P)/tmp/CLink.o: $(P)/src/CLink.cpp $(P)/include/CLink.h; $(CPP) -c $< -o $#
$(P)/tmp/CFetcher.o: $(P)/src/CFetcher.cpp $(P)/include/CFetcher.h; $(CPP) -c $< -o $#
$(P)/tmp/main.o: $(P)/src/main.cpp $(P)/include/CLink.h $(P)/include/CFetcher.h ; $(CPP) -c $< -o $#
all:
touch $(P)/tmp/*.o;
touch main;
rm -f $(P)/tmp/*.o;
rm -f main;
make main;
The Compiler output is lie
g++ -c -g -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -c src/main.cpp -o tmp/main.o
g++ -c -g -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -c src/CLink.cpp -o tmp/CLink.o
g++ -c -g -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -c src/CFetcher.cpp -o tmp/CFetcher.o
g++ -g ./tmp/main.o ./tmp/CLink.o ./tmp/CFetcher.o -I/usr/local/include/cpp-netlib -lboost_system -lboost_filesystem -lboost_thread -lpthread -o main
So for me all looks nice but when i try to run the program
./main
./main: error while loading shared libraries: libboost_system.so.1.46.1: cannot open shared object file: No such file or directory
The -l flags must come after the source files on linker command-line.
Yes, that means you'll have to split the LD definition to LD and LIBS, put all the -L and -l flags in the later and change the link command to:
$(LD) $(OBJ) $(LIBS) -o $#
The library (.so (dynamic) or .a (static)) files have to be the same version as the headers. While there are boost 1.46.1 headers installed in /usr/local/include/boost_1_46_1/, the corresponding library files don't seem to be installed at all. The only installed libraries are version 1.40.0 in /usr/lib, so the linker finds those (/usr/lib would be searched by default even if you didn't include the -L/usr/lib flag), but they don't contain the symbols expected by 1.46.1.
Note that when linking against shared library (using shared libraries is strongly recommended in Linux), the linker looks for the file with .so extension, but that is usually symlink to a file with added version suffix and the linker reads it and records the target name in the binary. That way programs compiled against the .1.40 will continue to work when 1.46 is installed, because the libboost*.so.1.40.0 may (and have to) stay around after the .so is redirected to the 1.46.1 version.
It should be even possible to install like:
/usr/local/lib/boost_1_46_1/libboost_system-mt.so -> /usr/local/lib/libboost_system-mt.so.1.46
/usr/local/lib/libboost_system-mt.so.1.46 -> /usr/local/lib/libboost_system-mt.so.1.46.1
/usr/local/lib/libboost_system-mt.so.1.46.1
and compile using -L/usr/local/lib/boost_1_46_1, though I currently can't find any package that would do it to confirm this. This way you could have development files for multiple versions installed and switch between them using explicit -I and -L flags while dynamic linker would still find the runtime files, for which it only looks in /usr/local/lib, /usr/lib and /lib (it can be configured in /etc/ld.so.conf, but that's the default).
Execute your application with strace. This will show the location were you app is looking for your boost libs. In my case an app was looking in /usr/lib/x86_64-linux-gnu for boost libs where the actual location was /usr/lib/lib. A simple export statement adding the paths for the boost shared libs in my case LD_LIBRARY_PATH=/usr/lib/lib worked a treat.
output from strace
open("/usr/lib/x86_64-linux-gnu/libboost_system.so.1.46.1", O_RDONLY) = -1 ENOENT (No such file or directory)
exit_group(127) = ?