How to find actual location of library used by linker (gcc) - gcc

I have this compile command
qcc -Vgcc_ntoarmv7le -lang-c++ -Wl,-rpath-link,\
C:\Users\mureadr\Desktop\A\QNX_SDK\target\qnx6/armle-v7/lib -Wl,-rpath-link,\
C:\Users\mureadr\Desktop\A\QNX_SDK\target\qnx6/armle-v7/usr/lib -Wl,-O1 -Wl,-rpath,\
C:/fs/mp/qt5/lib -Wl,-rpath,C:/fs/mp/fordhmi/lib -shared -Wl,-soname,libHmiLogging.so.1\
-o libHmiLogging.so.1.0.0 .obj/hmiloggingcategory.o .obj/hmiloggingcategoryregistry.o\
.obj/hmiperformancelogging.o .obj/hmitracelogging.o\
-LC:\Users\mureadr\Desktop\A\QNX_SDK\target\qnx6/armle-v7/lib \
-LC:\Users\mureadr\Desktop\A\QNX_SDK\target\qnx6/armle-v7/usr/lib \
-LC:/Users/mureadr/Desktop/A/HMI_FORGF/qt5binaries/lib -lQt5Core \
-LC:/QNX650/target/qnx6/armle-v7/lib -LC:/QNX650/target/qnx6/armle-v7/usr/lib -lm
When I run it under make, it runs fine but using another build system, I get the error
C:\Users\mureadr\Desktop\A\QNX_SDK\host\win32\x86\usr\bin\ntoarm-ld: cannot find -lQt5Core
cc: C:/Users/mureadr/Desktop/A/QNX_SDK/host/win32/x86/usr/bin/ntoarm-ld caught signal 1
Obviously the other build system doesn't have access to all the included directories.
Question
How can I find out which directory Qt5Core was pulled from?
Is there a linker option that will make it say I got Qt5Core from directory X?
I ran make with --debug=a but I didn't get any info about Qt5Core.

Is there a linker option that will make it say I got Qt5Core from directory X?
Yes. It is -trace. To pass it via gcc, use gcc ... -Wl,-trace....
This will cause the linker to print the name of each input (object file or library) that
it receives from the commandline together with the absolute path where it located
the same.
BTW, passing debug options to make will produce debugging info from make
but none from tools that are invoked by make.

Related

ld: building for macOS-x86_64 but attempting to link with file built for macOS-x86_64

I have this strange issue where creating / using a static library works in my Ubuntu VM but not on macOS:
ld: warning: ignoring file ./dist/libXXXX.a, building for macOS-x86_64 but attempting to link with file built for macOS-x86_64
Command to create the static library is:
ar rcs libtest.a obj1.o obj2.o ...
Compiler invocation:
gcc -g -Wall -Wextra main.c -L./dist -lXXXX -o main
Searching on google didn't yield any usable results except for this (maybe) related question on SO:
Possible related question
I realize this is an old post and you found your fix, but let me post this here for anyone else who runs into this problem for whom these answers don't provide a solution.
You might be using two different toolchains unknowingly, one from Apple (installed via Xcode) and one from GNU (installed via Home-brew or MacPorts). If you type ranlib --version and see version info showing that ranlib is GNU, this is likely the case.
Make sure that /usr/bin comes in your $PATH before /usr/local/bin and /opt/local/bin. When you run which -a ranlib, the first result in the list should be /usr/bin/ranlib. Same for which -a ar-- the first result should be /usr/bin/ar. If it is not so, you need to fix your $PATH.
Once you fix your path and clean your project, try building again and things should work.
The issue was solved when I directly put those object files rather than gathering them into a static library, i.e.,
gcc -g -Wall -Wextra main.c obj1.o obj2.o -o main
After that, I got many warnings like ld: warning: object file (obj1.o) was built for newer macOS version (11.0) than being linked (10.14), but it is a warning, and the object is linked, so the problem is solved.
The root cause is that some library passes -mmacosx-version-min=10.14 to gcc, so the object file is built for 10.14, but my macos is now 11.0.
If you want to make things work, try directly using object files rather than creating a static library.
If you want to resolve all the warnings, find ``-mmacosx-version-min` and comment it.
After looking at my script that automatically creates the static library I've found the culprit:
For some reason my tool created object files for header files (resulting in files like header.h.o).
Removing those fixed the issue.

How to make compiler generate a "elf32-x86-64" format object file?

First, some background info about elf32-x86-64 format.
It is a format that leverages 64-bit hardware while enforcing 32-bit pointers. Ref1 and Ref2.
Question
I am trying to link the Google Test framework binaries to my project.
I use objdump -f to check the format of Google Test binaries and my binaries.
Google Test format is elf64-x86-64. Mine elf32-x86-64. So they cannot be linked together.
Then I add below content to the google test's internal_utils.cmake file:
set(ZEPHYR_LINK_FLAGS "-Wl,--oformat=elf32-x86-64")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ZEPHYR_LINK_FLAGS}")
I hope the linker flag can change the output format to elf32-x86-64.
But google test build failed with below error:
/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so: error adding symbols: File in wrong format
The /usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so is also a elf64-x86-64 format.
And I checked the generated object file, such as:
./googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
It is still elf64-x86-64.
So it seems the linker flag doesn't affect the object file format.
I remember the linker ld will choose the output format based on its first encountered object file. So I guess I need to tell the compiler to output a elf32-x86-64 format.
How can I ask the compiler to output a elf32-x86-64 object file?
ADD 1 - 3:29 PM 11/1/2019
I have managed to compile the Google Test as elf32-x86-64 with below tuning:
Add compile flag -mx32
And add link flag -Wl,--oformat=elf32-x86-64
Now the output binaries libgtest.a, libgtest_main.a are elf32-x86-64. But they need to be linked to libstdc++.so. So far, it is elf64-x86-64 on my system. And I haven't found a elf32-x86-64 one. Thus below error:
/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so: error adding symbols: File in wrong format
ADD 2 - 3:47 PM 11/1/2019
After installing sudo apt-get install gcc-multilib g++-multilib (ref), I got a elf32-x86-64 version of libstdc++.so at below location:
/usr/lib/gcc/x86_64-linux-gnu/7/x32/libstdc++.so
And it ultimately points to /usr/libx32/libstdc++.so.6.0.25
Now it seems I just need to find a way to tell the linker to use it... So close!
ADD 3 - 2:44 PM 11/4/2019
Thanks to Florian and EmployedRussian, I change Google Test's internal_utils.cmake file to add below 4 lines:
set(MY_COMPILE_FLAGS "-mx32")
set(cxx_base_flags "${cxx_base_flags} ${MY_COMPILE_FLAGS}")
set(MY_LINK_FLAGS "-mx32")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MY_LINK_FLAGS}")
Now the generated executable are elf32_x86-64 format.
So basically, I add the -mx32 to both compile and link flags.
And in the generated rules.ninja file, the link rule goes like this:
command = $PRE_LINK && /usr/bin/c++ $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
The $FLAGS and $LINK_FLAGS are defined in the build.ninja file as below:
FLAGS = -Wall -Wshadow -Werror -mx32 ...
LINK_FLAGS = -mx32 ...
So essentially, there are 2 -mx32 options in the ninja command definition contributed by the $FLAGS $LINK_FLAGS respectively.
So why do I need to specify the -mx32 for twice??
And I don't understand why I can specify -mx32 for CMAKE_EXE_LINKER_FLAGS.
First, -mx32 is only a compile option (ref), not a linker option.
Second, from the link rule definition, the $LINK_FLAGS are passed to usr/bin/c++ without a -Wl, prefix, so even the option can be appreciated by the linker, it won't be passed to the linker.
GCC will adjust the linker command line accordingly if you invoke it as gcc -mx32. It is more than just a compiler flag.

Errors when compiling wxWidgets

I'm following this tutorial to begin with Code::Blocks using wxWidgets.
Following the tutorial, my first step was:
cd C:\wxWidgets-3.0.3\build\msw
Since I have the mingw32-make.exe installed in the directory C:\Program Files\CodeBlocks\MinGW\bin, next I do the following (again based on the tutorial):
C:\wxWidgets-3.0.3\build\msw>"C:\Program Files\CodeBlocks\MinGW\bin\mingw32-make" -f makefile.gcc BUILD=release SHARED=0 MONOLITHIC=1 UNICODE=1 CXXFLAGS=-fno-keep-inline-dllexport
The output I get is:
gcc -c -o gcc_mswu\wxregex_regcomp.o -O2 -mthreads -DHAVE_W32API_H -DNDEBUG -I
..\..\include -I..\..\lib\gcc_lib\mswu -D__WXMSW__ -D_UNICODE -MTgcc_mswu\wxr
egex_regcomp.o -MFgcc_mswu\wxregex_regcomp.o.d -MD -MP ../../src/regex/regcomp.c
gcc: error: CreateProcess: No such file or directory
makefile.gcc:5702: recipe for target 'gcc_mswu\wxregex_regcomp.o' failed
mingw32-make: *** [gcc_mswu\wxregex_regcomp.o] Error 1
I think that gcc is not found, so I need to edit the makefile.gcc
Am I right?
I'm not used to makefiles, so, I apologize but I need some help.
Open a command box and cd C:\wxWidgets-3.0.3\build\msw
Type and press enter:
PATH=%PATH%;C:\Program Files\CodeBlocks\MinGW\bin
This will add the mingw needed files (they execute chained) to your PATH, only for the command box. If you want it permanent, modify PATHenviroment var in you Windows settings.
Now run the command to compile wxWidgets:
mingw32-make" -f makefile.gcc BUILD=release SHARED=0 MONOLITHIC=1 UNICODE=1 CXXFLAGS="-std=gnu++11" The std=gnu+11 flag is default (not needed) if your mingw version uses gcc >=5.2. Use it anyhow, it's harmless.
Adding RUNTIME_LIBS=static may avoid to have a couple of mingw libs visible (on the path). This way you can run your app without providing those libs.
Probably you'll get zillions of warnings (not errors) about "deprecating" with BestSize. That's a gcc <5.3 bug, not wx one.
You can get rid of those messages modifying a few lines at include/wx/window.h But better don't use the old version that ships with CB and download the newest one from http://www.mingw.org/

Can't make FestVox compile due to missing -leststring and missing libeststring.a

So I have installed / compiled speech_tools, and Festival (2.3) using Cygwin on my Win8.1 machine to the point that I can successfully produce speech using this command:
echo "hello world" | \src\main\festival --tts
The next step is for me to get FestVox running. I have downloaded FestVox 2.6 and I have run ./configure; however, the 'make' step is giving me trouble, producing this error:
gcc -O3 -Wall -o phonealign phonealign_main.o -LC:/cygwin64/Festival/build
/speech_tools/lib -lestools -lestbase -leststring -lncurses -lstdc++ -lm -lwinmm -luser32
/usr/bin/ld: cannot find -leststring
collect2: error: ld returned 1 exit status
Makefile:80: recipe for target 'phonealign' failed
So, I looked at my Makefile at where it might be trying to look for this file, and it looks like in that directory (build\speech_tools\lib) I am missing a libeststring.a partner for my libeststring.lib. Both libestbase and libestools have .lib and .a files in that directory.
At what step did I go wrong?? Should a libeststring.a have been created at some point??? When? How can I fix this?
I think the problem is that you should use compiler in Windows instead of gcc within Cygwin. The role in Cygwin for building Festival is to run configure to generate a Makefile for VC. Then run nmake in Windows command line not make within Cygwin.
Cygwin cannot build a native Windows application like what MINGW does. Application build in Cygwin can only run within Cygwin.
*.a is the static library for Linux, which is built by gcc. *.lib is the static library for Windows, which is built by VC.
So I suggest you taking a look at README, INSTALL files in FestVox. To find whether there is description for make a Makefile for Windows like process "3. Make makefile for VC in Cygwin" in my document (http://www.eguidedog.net/doc_build_win_festival.php)
Cameron

mingw32-make tries to create subfolder .lib an illegal name

I am trying to compile a project that required freetype library so I was figuring out how to install freetype to mingw32 and the more safer way is to compile it.
Anyway the problem was compiling freetype-2.4.11
I went into bash provided in msys
I did ./configure within freetype's main dir and everything looks fine
next I did mingw32-make which created the problem
libtool: compile: gcc -pedantic -ansi -Ig:/Downloads/freetype-2.4.11/objs -I./b
uilds/unix -Ig:/Downloads/freetype-2.4.11/include -c -Wall -g -O2 "-DFT_CONFIG_C
ONFIG_H=<ftconfig.h>" -DFT2_BUILD_LIBRARY "-DFT_CONFIG_MODULES_H=<ftmodule.h>" g
:/Downloads/freetype-2.4.11/src/base/ftsystem.c -DDLL_EXPORT -DPIC -o g:/Downlo
ads/freetype-2.4.11/objs/.libs/ftsystem.o
Assembler messages:
Fatal error: can't create g:/Downloads/freetype-2.4.11/objs/.libs/ftsystem.o: No
such file or directory
g:/Downloads/freetype-2.4.11/builds/freetype.mk:198: recipe for target 'g:/Downl
oads/freetype-2.4.11/objs/ftsystem.lo' failed
mingw32-make[4]: *** [g:/Downloads/freetype-2.4.11/objs/ftsystem.lo] Error 1
g:/Downloads/freetype-2.4.11/objs/.libs/ftsystem.o seemed like it is trying to use a directory that is illegal in windows.
Thanks in advance
Try to use make instead (i.e. the one from MSYS distribution), and avoid using mingw32-make (from MinGW distribution) in the future to save yourself time and nerves. Extract from MinGW Wiki:
What's the difference between make and mingw32-make?
The "native" (i.e.: MSVCRT dependent) port of make is lacking in some functionality and has modified functionality due to the lack of POSIX on Win32. There also exists a version of make in the MSYS distribution that is dependent on the MSYS runtime. This port operates more as make was intended to operate and gives less headaches during execution. Based on this, the MinGW developers/maintainers/packagers decided it would be best to rename the native version so that both the "native" version and the MSYS version could be present at the same time without file name collision.

Resources