qmake -query internal settings in Linux - where are they? - linux

I am building a Linux system with cross-compiler using ptxdist. It allows me to configure Qt4 for installation and it builds and installs qt-everywhere-opensource-src-4.6.3 Ok. However, the qmake internal settings are screwed up and I don't know how to fix them.
When I run qmake -query I get:
me#ubuntu:~$ qmake -query
QT_INSTALL_PREFIX:/
QT_INSTALL_DATA:/
QT_INSTALL_DOCS://doc
QT_INSTALL_HEADERS://include
QT_INSTALL_LIBS://lib
QT_INSTALL_BINS://bin
QT_INSTALL_PLUGINS://plugins
QT_INSTALL_TRANSLATIONS://translations
QT_INSTALL_CONFIGURATION:/etc/xdg
QT_INSTALL_EXAMPLES://examples
QT_INSTALL_DEMOS://demos
QMAKE_MKSPECS://mkspecs
QMAKE_VERSION:2.01a
QT_VERSION:4.6.3
Through some research, it looks like this can be fixed by simply rebuilding Qt, but it's not fixing this problem. I dug into the build output a bit and it looks like the ./configure command for the Qt build has "-prefix /usr" so I don't know why this isn't being fixed.
I would like to fix these internal values manually if possible because the Qt build takes hours. Does anyone know how to do this?

At configure time these paths are hardcoded in 'src/corelib/global/qconfig.cpp', and end up hardcoded into qmake when it is built. They are also hardcoded into many other files, like all the .la and .pc files, not to mention the Makefile install rules.
The only way to fix this is to figure out why configure keeps screwing up the prefix. configure is a big shell script, so it's easy to see where $QT_INSTALL_PREFIX is assigned from the '-prefix' argument, and then the different checks that are done on it (like running it through 'config.tests/unix/makeabs'). Try putting print statements before/after $QT_INSTALL_PREFIX is changed, and you should be able to find out where the path gets screwed up.
Also, you don't have to wait for the full build to complete to tell if the prefix was set
correctly. After configure runs, take a look in 'src/corelib/global/qconfig.cpp' and see what 'qt_configure_prefix_path_str' is set to.

You can manually set these properties using
qmake -set VARIABLE VALUE
They are stored using QSettings, the Qt built-in persistent applications settings.
see Configuring qmake's Environment

Configure scripts can be fuzzy about slashes. Are you sure that the build prefix is /usr and not /usr/ .

Related

environment variable LD_LIBRARY_PATH is not working until I reassign it

I have a strange behavior on an embedded linux system. It is created from an image file and has been used on many system for about a year without any issues. But a new system that I installed just now fail to work.
I have an app that is started by one of the boot scripts, and is dependent on a library foo.so in a special path.
So the script sets LD_LIBRARY_PATH to foopath.
LD_LIBRARY_PATH=foopath \
foo.app
But after boot I can see that the app was never started and if I try to start it manually it complains that it can't find the library.
The strange thing is that I can get it to work by setting the same path again by just copying the path using the clipboard, like this:
$ echo $LD_LIBRARY_PATH
foopath
$ export LD_LIBRARY_PATH=foopath
After this my app will find the library and executes correct.
But if I reboot the system the problem is of course back again.
What could be wrong, and what can I do to solve the issue?
As seen in the comments I got it to work by changing my script like this, but I still can't understand why it works on some systems, but not all.
export LD_LIBRARY_PATH=foopath
foo.app

llvm-sys - Didn't find usable system wide LLVM. But llvm-config is installed

I have built llvm-13.0.1 from source using Visual Studio 17 2022 on Windows 11. When attempting to build llvm-sys (through external crate llvm-ir). It fails, saying:
error: No suitable version of LLVM was found system-wide or pointed to by LLVM_SYS_130_PREFIX.
I know llvm-config exists because I can use it from the command line, and it returns the correct version. I don't understand why this doesn't work. This might be a stupid question but I am really stuck.
I was also having this problem, trying to use llvm-sys on Windows. Here are some mistakes that I did that made it fail to compile just like yours.
Installation Prefix
Make sure that your LLVM installation path doesn't have any whitespace.
Mine was -DCMAKE_INSTALL_PREFIX=C:\Program Files (x86)\LLVM, which was their default install prefix. The whitespace in the installation path causes some errors when using it with llvm-sys. Later, I changed it to C:\LLVM and it worked.
Set Environment Variable
Set Environment Variable LLVM_SYS_<version>_PREFIX to the installed LLVM folder.
From CMD For LLVM-13.0.1
setx LLVM_SYS_130_PREFIX "<PATH TO LLVM WITHOUT WHITESPACE>" /M
Make sure that the variable is registered by using echo command
echo %LLVM_SYS_130_PREFIX%
It should output your registered path, not %LLVM_SYS_130_PREFIX%.
If it doesn’t output your path, restart the computer and try again and it should be working.
Now you should be good to go .....
Hope this helps :)

How to install Gnatcoll Postgres on Linux Centos 7

I have installed gprbuild, xmlada, and gnatcoll. I am now attempting to install gnatcoll_postgres. Which I have downladed from here: https://github.com/AdaCore/gnatcoll-db/
Within the Postgres folder is a Makefile, which I execute like so...
[parallels#localhost postgres]$ ls
gnatcoll_postgres.gpr gnatcoll-sql-postgres-gnade.ads
gnatcoll-sql-postgres.adb gnatcoll-sql-ranges.adb
gnatcoll-sql-postgres.ads gnatcoll-sql-ranges.ads
gnatcoll-sql-postgres-builder.adb Makefile
gnatcoll-sql-postgres-builder.ads postgres_support.c
gnatcoll-sql-postgres-gnade.adb README.md
[parallels#localhost postgres]$ make Makefile
which: no gnatls in (/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/var/lib/snapd/snap/bin:/home/parallels/.local/bin:/home/parallels/bin)
make: Nothing to be done for `Makefile'.
[parallels#localhost postgres]$
Would anybody please be able to tell me what this means...
which: no gnatls in (/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/var/lib/snapd/snap/bin:/home/parallels/.local/bin:/home/parallels/bin)
make: Nothing to be done for `Makefile'.
Any help would be greatly appreciated.
Please see the xmlada and gnatcoll in my project below, does this look like it's installed correctly? I'm presuming this isn't correct...
Thanks,
Lloyd
It means that your GNAT installation binaries aren’t on your PATH.
The README.txt from the adacore.com site says, in part,
To start using the tools in command-line mode, you will need to add
{install_prefix}/bin
to your PATH environment variable. Alternatively, you can simply launch
{install_prefix}/bin/gps
and GPS will automatically add itself to the PATH - it will also find the
cross compiler, if you have installed everything in the default locations.
Note that GPS will add this at the end of the PATH, meaning that it will find first any other GNAT installations that you have in your PATH.
I strongly suspect that you’ve been doing the latter, so that GPS adds itself (actually, of course, its own location) to the PATH, so that when it launches the compiler it finds the correct one.
When you run make from the terminal, the compiler isn’t on the PATH, so neither are gnatls, gprconfig, gprbuild and the rest of the GNAT tools.
What you need to do is to take the first choice from the README, and add /home/parallel/opt/GNAT/2019/bin to (the front of) your default PATH. How you do that depends on your shell.
You will find xmlada, gnatcoll already installed.

Set linker search path for build in CMake

It seems this question has been asked very often before but none of the solutions seem to apply in my case.
I'm in a CMake/Linux environment and have to run an executable binary during the build step (protoc in particular).
This binary needs a library but it's not installed (and cannot be) in the in the standard directories like /usr, so the library cannot be found.
Unfortunately I cannot manipulate the protoc call because it's embedded in a 3rd party script.
I can now set LD_LIBRARY_PATH before every make or set it system wide but this is very inconvenient especially when it comes to IDEs in which the build takes place or distributed build scenarios with continuous build environments.
I tried to set LD_LIBRARY_PATH via
set(ENV{LD_LIBRARY_PATH} "/path/to/library/dir")
but this seems to have no effect during the build step.
So my question is: can I set a library search path in CMake which is used during the build?
Try this
SET(ENV{LD_LIBRARY_PATH} "/path/to/library/dir:$ENV{LD_LIBRARY_PATH}")
I also used this dirty trick to temporary change some environment variables:
LD_LIBRARY_PATH="/path/to/library/dir:$LD_LIBRARY_PATH" cmake ...
After execution of this line LD_LIBRARY_PATH is not changed in the current shell.
Also, I do not find it bad to change LD_LIBRARY_PATH before invoking cmake:
export LD_LIBRARY_PATH=...
It won't change anything system-wide, but it would be used for your current shell, current build process. The same holds for CI builds. You can save the variable and restore it after cmake invocation:
MY_LD=$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=...
cmake...
export LD_LIBRARY_PATH=$MY_LD
I have recently run into a somewhat similar problem.
My solution was to incorporate sourcing a file that set the appropriate environment into every command.
For example, this custom command:
add_custom_command(
OUTPUT some_output
COMMAND some_command
ARGS some_args
DEPENDS some_dependencies
COMMENT "Running some_command some_args to produce some_output"
)
Would become:
set(my_some_command_with_environment "source my_environment_script.sh && some_command")
add_custom_command(
OUTPUT some_output
COMMAND bash
ARGS -c "${my_some_command_with_environment} some_args"
DEPENDS some_dependencies
COMMENT "Running some_command some_args to produce some_output"
VERBATIM
)
Obviously, this has some disadvantages:
It relies on a bash shell being available.
It sources the environment script for every command invocation (performance issue) and you will have to change all invocations of commands that rely on that environment variables.
It changes the normal syntax of having the command follow COMMAND and the arguments follow ARGS, as now the 'real' command is part of the ARGS.
My CMake-Fu has proven insufficient to find a syntactically nicer way of doing this, but maybe somebody can comment a nicer way.
I had a similar issue for an executable provided by a third party library. The binary was linked against a library not provided by the distribution but the required library was included in the libs directory of the third party library.
So running LD_LIBRARY_PATH=/path/to/thirdparty/lib /path/to/thirdparty/bin/executable worked. But the package config script didn't set up the executable to search /path/to/thirdparty/lib for the runtime dependent so CMake would complain when CMake tried to run the executable.
I got around this by configuring a bootstrap script and replacing the IMPORTED_LOCATION property with the configured bootstrapping script.
_thirdpartyExe.in
#!/bin/bash
LD_LIBRARY_PATH=#_thirdpartyLibs# #_thirdpartyExe_LOCATION# "$#"
CMakeLists.txt
find_package(ThirdPartyLib)
get_target_property(_component ThirdPartyLib::component LOCATION)
get_filename_component(_thirdpartyLibs ${_component} DIRECTORY)
get_target_property(_thirdpartyExe_LOCATION ThirdPartyLib::exe IMPORTED_LOCATION)
configure_file(
${CMAKE_CURRENT_LIST_DIR} _thirdpartyExe.in
${CMAKE_BINARY_DIR}/thirdpartyExeWrapper #ONLY
)
set_target_properties(ThirdPartyLib::exe PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/thirdpartyExeWrapper)
Honestly I view this as a hack and temporary stop gap until I fix the third party library itself. But as far as I've tried this seems to work on all the IDE's I've thrown at it, Eclipse, VSCode, Ninja, QtCreator, ... etc

Can I tell FIND_LIBRARY to run after my *custom* dependency has been built?

[Note: This is ALMOST a duplicate of Linking to a library that hasn't been built yet with CMake, but in this case the unbuilt library is coming from an ADD_CUSTOM_TARGET rather than an ADD_LIBRARY, so CMake can't work its usual magic so effectively.]
One of my CMake 2.8 projects currently has the following code:
# the COMMAND was heavily simplified but you get the idea
ADD_CUSTOM_TARGET(custom_breakpad_target ALL
COMMAND cd ${CMAKE_SOURCE_DIR}/google-breakpad && make
)
# now here we are in the root "CMakeLists.txt"
LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/google-breakpad/src/client/linux)
ADD_EXECUTABLE(hello)
# ...many lines of code...
ADD_DEPENDENCIES(hello custom_breakpad_target)
TARGET_LINK_LIBRARIES(hello breakpad)
I know that LINK_DIRECTORIES has been deprecated (or at least disdained) because of its weird placement (it has to go before ADD_EXECUTABLE even though we'd really like to put it down next to the TARGET_LINK_LIBRARIES). Also, there's this nifty new command FIND_LIBRARY. So I'd like to write the root "CMakeLists.txt" more like this:
ADD_EXECUTABLE(hello)
# ...many lines of code...
ADD_DEPENDENCIES(hello custom_breakpad_target)
FIND_LIBRARY(breakpad breakpad ${CMAKE_SOURCE_DIR}/google-breakpad/src/client/linux)
TARGET_LINK_LIBRARIES(hello breakpad)
This code works fine... until I "make clean". The next rebuild fails to find breakpad, because it has been rm'ed and not created again yet by the time the FIND_LIBRARY runs.
How can I make this work? or make something work that's more elegant than what I've got?
So far, the best I've got is
ADD_EXECUTABLE(hello)
# ...many lines of code...
ADD_DEPENDENCIES(hello custom_breakpad_target)
TARGET_LINK_LIBRARIES(hello ${CMAKE_SOURCE_DIR}/google-breakpad/src/client/linux/libbreakpad_client.a)
This has the aesthetic disadvantage of having to explicitly write out the "libxxx.a" filename, whereas, as I understand it, FIND_LIBRARY would uncomplainingly continue to work even if we switched to "libxxx.1.so".
Building external targets through custom commands is very difficult to get right. CMake offers the ExternalProject module to assist with that.
With this module external libraries get build at CMake configure time - that is when running cmake for the first time and not when running make to build your actual project. This has the advantage that all of the files are already in place when configuring your project, so it is easy to locate them using a find script or a CMake configure file.
This approach of course only makes sense if the external library does not change frequently, because rebuilding the library requires running CMake again. If you need to recompile the external library upon changes by just running make, the best way to make it work is still to write a full-fledged CMakeLists.txt for it and pull that in with add_subdirectory.

Resources