What is the easiest way to reference libraries in Qt projects? - qt

I have two Qt4 Gui Application projects and one shared library project, all referenced under a .pro file with the "subdirs" template. So, it's like:
exampleapp.pro
app1.pro
app2.pro
sharedlib.pro
Now, what I want to do is reference sharedlib from app1 and app2 so that every time I run app1.exe, I don't have to manually copy sharedlib.dll from its own folder to app1.exe's folder.
I could set PATH environment variable in the projects window, but this isn't very portable. I've looked at putting the LIBS variable in the app1.pro file, but I'm not sure if that refers to statically linked libraries only - I've tried it with various syntaxes and it doesn't seem to work with shared libs.

You can organize your project as follows:
Project1
bin
lib
app1
app2.pro
app2
app2.pro
sharedlib
sharedlib.pro
in sharedlib.pro can add something like this:
TEMPLATE = lib
TARGET = sharedlibr
QT + = core \
gui
DESTDIR = .. / lib
DESTDIR: guarantees that the result of the compilation will be copied to the location ".. / lib"
as for applications app1 and app2:
TEMPLATE = app
TARGET = app1
QT + = core \
gui
DESTDIR = .. / bin
this only for development, when creating the installer, the libraries and executables are placed in the appropriate dirs, depending of the operating system.

To add to this (a bit late!), one can use QMAKE_POST_LINK to copy files around after a build has been completed. Example:
defineReplace(formatpath) {
path = $$1
win32 {
return(\"$$replace(path, "/", "\\")\")
} else:unix {
return($$replace(path, " ", "\\ "))
} else {
error("Unknown platform in formatpath!")
}
}
win32:COPY_CMD = copy
unix:COPY_CMD = cp -P
macx:COPY_CMD = cp -R
win32:CMD_SEP = $$escape_expand(\n\t)
unix:CMD_SEP = ";"
win32:LIB_EXT = dll
unix:LIB_EXT = so*
macx:LIB_EXT = dylib
# Put here the directory of your library's build dir, relative to the current directory
# A path is given for example...
MYLIB_BUILD_DIR = $$_PRO_FILE_PWD_/../lib/bin
QMAKE_POST_LINK += $$COPY_CMD $$formatpath($$MYLIB_BUILD_DIR/*.$$LIB_EXT) $$formatpath($$OUT_PWD/$$DESTDIR) $$CMD_SEP

Related

How to get platform dependent output filename with QMake?

Assume I have a qmake project file *.pro:
# some stuff ...
TARGET = my_binary
# other stuff...
include( $$PWD/post.pri )
And inside the post.pri file (because I would like to reuse whatever this *.pri file does), I would like to get the complete name of the output file.
For example if is an app, then on windows I would like to get my_binary.exe and on linux my_binary. Or if the project is a shared lib, I would like to get my_binary.dll or libmy_binary.so respectively. Same if is a static lib, I would expect my_binary.lib and libmy_binary.a.
I have already tried the undocumented qmake variable QMAKE_FILE_OUT but with no success.
You can do this in your .pro script:
load(resolve_target)
message($$QMAKE_RESOLVED_TARGET)
It will output the build path and target name, according to your platform and project TEMPLATE.

Problems with libraries in premake

I have experienced certain problems when using libraries in premake4 scripts.
1) When creating a shared library (.dll) on Windows 10 using a premake4 script, it creates the dll fine, but it also creates a static library of small size (2K).
In my case, I was creating a shared library named MathLib.dll using a premake4 script. It did that correctly, but it also created a file named libMathLib.a of size 2K. (It may be empty.)
I don't see why there was a need for the Makefile generated by premake4 to create libMathLib.a, when in fact the objective was to create a .dll file. I think this may be a premake4 bug and I have raised it on the premake4 Issue tracker on github.
The premake4 lua script is as follows:
-- Dir : Files > C > SW > Applications > Samples >
-- premakeSamples > premake-sharedlib-create
--#!lua
-- A solution contains projects,
-- and defines the available configurations
solution "MathLib"
configurations { "Debug", "Release" }
-- A project defines one build target
project "MathLib"
kind "SharedLib"
language "C++"
files { "**.h", "**.cpp" }
includedirs {"../../../ProgramLibraries/Headers/"}
-- Create target library in Files > C > SW >
-- Applications > ProgramLibraries
targetdir "../../../ProgramLibraries/"
configuration "Debug"
defines { "DEBUG" }
flags { "Symbols" }
configuration "Release"
defines { "NDEBUG" }
flags { "Optimize" }
-- Register the "runmakefile" action.
newaction
{
trigger = "runmakefile",
description = "run the generated makefile to create the executable using the default ('debug' config)",
execute = function()
os.execute("make")
end
}
-- Register the "runmakefilerelease" action.
newaction
{
trigger = "runmakefilerelease",
description = "run the generated makefile to create the executable using the 'release' config)",
execute = function()
os.execute("make config=release")
end
}
2) The above problem is more serious than it sounds. Supposing I had already created a genuine static library named libMathLib.a in the Libraries dir, using a separate premake4 script. Subsequently, if I also create a shared library named MathLib.dll in the same directory as the static library, a dummy static library (possibly empty) would be created and replace the earlier genuine static library.
3) -- EDIT -- : I had reported this point (use of a static library) as a problem, but it has started working now. I don't know the reason, but the only difference, as far as I am aware, is that I had shut down and restarted my PC (and therefore my MSYS session on Windows 10). Therefore I am deleting this point.
How can I solve the above 2 problems?
That's the import library. You can turn it off with Premake's NoImportLib flag.
flags { "NoImportLib" }

Build docker image with custom config with sbt-native-packager

I am building my docker image for my scale application with sbt-native-packager.
Now I need to introduce staging and followed the recipe from the sbt-native-packager site. The problem is, that the the mapped application.conf is not picked up on boot.
I have adjusted the build.sbt from the recipe by the main class.
lazy val testPackage = project
.in(file("build/test"))
.enablePlugins(JavaAppPackaging)
.settings(
name := "app-dev",
mainClass := Some("Main"),
resourceDirectory in Compile := (resourceDirectory in (app, Compile)).value,
mappings in Universal += {
((resourceDirectory in Compile).value / "test.conf") -> "conf/application.conf"
}
).dependsOn(app)
I build the docker image as followed: testPackage/docker:publishLocal
I also played around with the bash_template file and added the -D parameter to pass the config file location (-Dconfig.file=${{chdir}}/conf/application.conf), but I did not get it running this way either.
How is it possible to add the custom application.conf to the class path?

How to create deb with custom layout

I have a Play server application.
Currently, I have 20-line bash script that creates this deb:
/srv
/foo
/conf
<unmanaged resources>
/staged
<jars>
I'd like to use sbt native packager to generate this.
Currently, sbt debian:package-bin gives me
etc/
default/
foo
foo
init/
foo.conf
usr/
bin/
foo
share/
foo/
bin/
foo
conf/
<unmanaged resources>
lib/
<jars>
share/
doc/
api/
<docs>
logs
README
var/
log/
foo/
How do I do I get my desired layout? Do I need to implement an archetype?
I'm using SBT 0.13.7 and SBT native packager 1.0.0-M1.
If your layout is close to the one already generated, you could use settings like defaultLinuxInstallLocation and defaultLinuxConfigLocation.
Or modify linuxPackageSymlinks and linuxPackageMappings directly, something like
linuxPackageSymlinks := Seq(),
linuxPackageMappings := {
val libPath = "/srv/foo/staged"
val libs = scriptClasspathOrdering.value.map { case (file, classpath) =>
file -> classpath.replaceFirst("^lib", Matcher.quoteReplacement(libPath))
}
Seq(LinuxPackageMapping(libs))
// plus configuration
},
If you have lots of binaries to archive (i.e. you have lots of dependencies), debian:packageBin is pretty slow. For debugging, consider using debianExplodedPackage.
Also, know that whatever is in the directory debianExplodedPackage will get included in the archive, so if there's extra stuff in the .deb at the end, you may need to delete that directory.

Google protobuf and symbian

I need to transfer data between c++ and java. I have decided to use Google's protobuf.
I made installation process and I got:
bin > protoc.exe
lib > libprotobuf.a
libprotobuf.la
libprotobuf-lite.a
libprotobuf-lite.la
libprotoc.a
libprotoc.la
and include folder
I've link library in .pro file
QT += core gui network webkit
TARGET = MWOP
TEMPLATE = app
LIBS += -LC:\msys\1.0\local\lib\ -lprotobuf
INCLUDEPATH += C:\msys\1.0\local\include
SOURCES +=
...
HEADERS +=
...
FORMS +=
...
CONFIG += mobility
MOBILITY += bearer systeminfo
symbian {
TARGET.UID3 = xxxxx
TARGET.CAPABILITY += ReadUserData NetworkServices
TARGET.EPOCSTACKSIZE = 0x14000
TARGET.EPOCHEAPSIZE = 0x020000 0x800000
}
RESOURCES += Resources/Registration.qrc
in simulator everything seems to work fine and project builds but when I want to deploy application on phone I've got compilation error:
:: error: No rule to make target \NokiaQtSDK\Symbian\SDK\epoc32\release\armv5\LIB\protobuf.dso, needed by \NokiaQtSDK\Symbian\SDK\epoc32\release\gcce\urel\MWOP.exe. Stop.
How can I fix that?
The DSO file you need is the ARM compiled protobuf library. I expect that the libs you list (libprotobuf.a etc) are windows/x86 binaries, so no use for running on target. You need to either:
get hold of the protobuf source code and build it yourself for ARM
find pre-compiled ARM binaries for the protobuf library
An alternative is to use the Nokia APIbridge, which can achieve the same thing

Resources