apt-get environment variables when spawning "debian rules" file - linux

What are the environment variables made available to debian/rules (often make) when spawned by apt-get during installation of a package under Ubuntu?
I am specifically after the environment variables that would pertain to Gnome's configuration directories. I'd like avoiding "hardcoding" things like ~/.conf/apps/ ... since I have been told these might change like they tend to...
I've been googling like crazy!

Are you looking for the XDG_CONFIG_HOME and related? In particular, note that XDG_CONFIG_HOME doesn't have to exist, and a value of ~/.config is assumed in that case.
Python example
import os
from os import path
app_name = "my_app"
home_config = path.join(
os.environ.get("XDG_CONFIG_HOME") or path.expanduser("~/.config"),
app_name,
)
print "User-specific config:", home_config
C++ example
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <string>
std::string get_home_config(std::string const& app_name) {
// also look at boost's filesystem library
using namespace std;
string home_config;
char const* xdg_config_home = getenv("XDG_CONFIG_HOME");
if (xdg_config_home && xdg_config_home[0] != '\0') {
home_config = xdg_config_home;
}
else {
if (char const* home = getenv("HOME")) {
home_config = home;
home_config += "/.config";
}
else throw std::runtime_error("HOME not set");
}
home_config += "/";
home_config += app_name;
return home_config;
}
int main() try {
std::cout << "User-specific config: " << get_home_config("my_app") << '\n';
return 0;
}
catch (std::exception& e) {
std::clog << e.what() << std::endl;
return 1;
}

debian/rules gets invoked at package build time (either the source or binary package) It does not get called during apt-get.
In fact, the .deb file (==binary package), does not contain a copy of debian/rules anymore. That file is only in the source package.
Furthermore, packages should normally not try to do things for a particular user, or make use of the configuration of a user. Debian packages are intended for software that is installed system-wide.
Although it's theoretically possible to make a personal package that installs something in /home, such a package is of very limited value.

Related

How to link properly Dcmtk with Qt for Linux?

My goal is open Dicom files and convert thes into cv::Mat to process them with Opencv.
I have compiled dcmtk 3.6.3 on ubuntu 18.4.1 and tried to link it with Qt 5.11.1 with Qt Creator 4.6.2 but failed to do so.
# pro file
QT += core
QT -= gui
TARGET = DcmtkTesting
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
DCMTK_PREFIX = "/home/ismail/dcmtk363"
DCMTK_LIBS_PREFIX=$$DCMTK_PREFIX"/lib"
DCMTK_INCLUDE=$$DCMTK_PREFIX"/include"
INCLUDEPATH+=$$DCMTK_INCLUDE
LIBS += -L$$DCMTK_LIBS_PREFIX
SOURCES += main.cpp
and for the main:
#include
#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmdata/dctk.h"
#include <dcmtk/dcmimgle/dcmimage.h>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
DicomImage *image = new DicomImage("test.dcm");
if (image != NULL)
{
if (image->getStatus() == EIS_Normal)
{
if (image->isMonochrome())
{
image->setMinMaxWindow();
Uint8 *pixelData = (Uint8 *)(image->getOutputData(8 /* bits*/));
if (pixelData != NULL)
{
/* do something useful with the pixel data */
}
}
} else
cout << "Error: cannot load DICOM image (" << DicomImage::getString(image->getStatus()) << ")" << endl;
}
delete image;
return a.exec();
}
and I got this errors:
The error indicates that the linker could not find the symbols (methods) provided by the library. In your .pro file, you pointed the linker to a directory where your library is located, but you forgot to specify which library should be linked.
So you have to modify the line LIBS +=... accordingly, e.g.:
LIBS += -L$$DCMTK_LIBS_PREFIX -ldcmtk
Since I don't know the actual name of the library, I use dcmtk in my example. You may have to adopt it to fit your build environment. Just make sure that you have the -l (lower case L), immediately followed by the library name.

Need to find java version number using c++ program

I'm new to C++ programming. So, which libraries or functions should I use in retrieving this info from the registry? Just give me a brief idea about the steps involved in retrieving the java version number from registry. I'm using VC++.
If java paths are properly set, you could just run java -version from code:
Using the code described here How to execute a command and get output of command within C++ using POSIX? :
#include <string>
#include <iostream>
#include <stdio.h>
std::string exec(char* cmd) {
FILE* pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
_pclose(pipe);
return result;
}
using like:
int main(void) {
std::cout << exec("java -version");
return 0;
}

I can't figure out how to link msi.lib to my Visual Studio C++ project

I'm trying to write a simple application that will enumerate all the ProductCodes installed on my machine.
I've started a new project in Visual Studio 2013, but whenever I build I get the error:
"LNK2019: unresolved external symbol _MsiEnumProductsExA#32 referenced in function _main"
I've been trying to figure out how to add msi.lib to my project include path, but I can't seem to figure it out.
Here's my code:
#define _WIN32_MSI 300
#include <Windows.h>
#include <iostream>
#include <string>
#include <Msi.h>
using namespace std;
int main() {
// Get a list of all installed MSIs
DWORD index = 0;
TCHAR currentProductCode[40] = {0};
unsigned int result = ERROR_SUCCESS;
// Open an MSI handle
while (ERROR_SUCCESS == result) {
result = MsiEnumProductsEx(NULL, "s-1-1-0",
MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE,
index, currentProductCode, NULL, NULL, NULL);
if (result == ERROR_SUCCESS) {
cout << "current ProductCode: " << currentProductCode;
}
index++;
}
return 0;
}
I've been trying to update the project's Property Pages by adding the path to the msi.lib to the "Library Directories" property, but that doesn't seem to work:
This is like Visual Studio 101, what am I missing?!
Goto Configuration Properties>Linker>Input
Add msi.lib in Additional Dependencies Thats it! Make sure you are using same calling conversion, which used to built the lib. i.e either stdcall or cdecl.

Is boost::asio::strand broken on Ubuntu 11.04 (boost_all_dev 1.42)

I have a program which uses an io_service and several threads.
It instantiates some number of socket objects. These objects each have a strand for synchronization. All calls to async_read(), async_write(), and similar functions go through strand_.wrap(boost::bind(...)). Each object also has an int interlock_ variable that is initialized to 0.
Inside one of these functions (the on-data-receive callback), I do the following:
Class::startRead(...)
{
...
boost::asio::async_read(socket_, boost::asio::buffer(ptr, 16384), boost::asio::transfer_at_least(1),
strand_.wrap(boost::bind(&EagerConnection::on_read, this, placeholders::error, placeholders::bytes_transferred)));
}
Class::on_read(...)
{
...
startRead();
assert(0 == __sync_fetch_and_add(&interlock_, 1));
onData_();
assert(1 == __sync_fetch_and_add(&interlock_, -1));
}
Because everything is synchronized through the strand, that first assert should never fire. However, it does fire! When I check the value in GDB, the end value of interlock_ is 2, which means that two separate calls to on_read() are active at the same time.
Does this mean that boost::asio::strand is broken? (I've already checked that I don't have any re-entrancy within the completion function -- the onData_ signal handler does not re-call on_data()).
Can the "early" startRead somehow cause an immediate re-entry? (Both the semantics of async_x and strand seem to indicate it can't)
If you really, really want to see the full context of the class, it's available as a gist: https://gist.github.com/979212
I have spotted a few minor(?) issues:
Minor: The initialization order of interlock_ and strand_ is switched. Fix it by declaring interlock_ _after_ the strand_ member;
The readIn function returns no value (uninitialized data). You probably intend to return n?
Good news:
Running with valgrind turned up clear.
Running with helgrind turned up clear (but: I'm not using threads in my minimal example, I guess; Don't know about boost::asio and boost::signals internals).
I am trying to reproduce things, but my installation fails to raise the asserts when doing this.
I tacked on the following fragment at the end of the gist:
int split(std::string const &src, char ch, std::string &oLeft, std::string &oRight)
{
std::size_t pos = src.find(ch);
if (pos == std::string::npos)
{
oLeft = src;
oRight.clear();
return 1;
} else
{
oLeft = src.substr(0, pos);
oRight = src.substr(pos+1);
return 2;
}
}
namespace {
boost::asio::io_service svc;
EagerConnection c(svc);
void onconnect()
{
std::cout << "ONCONNECT" << std::endl;
const char data[] = "GET / HTTP/1.0\r\n\r\n";
c.writeOut(data, sizeof(data));
}
void ondata()
{
std::cout << "ONDATA" << std::endl;
std::ostringstream oss;
char buf[1024];
int read;
while ((read = c.readIn(buf, 1024)))
oss.write(buf, read);
std::cout << "response: " << oss.str() << std::endl;
}
void ondisconnect()
{
std::cout << "ON__DIS__CONNECT" << std::endl;
}
}
int main(int argc, char* argv[])
{
if (argc>1 && argv[1])
{
c.onConnect_.connect(&onconnect);
c.onData_.connect(&ondata);
c.onDisconnect_.connect(&ondisconnect);
c.open(argv[1]);
svc.run();
}
return 0;
}
As you can see, I'm really trying to do the SimplestThingThatCouldPossiblyWork. My connect/reconnect is working nicely (including the increasing backoff time).
I compile this with
strand: strand.cpp
g++ -Wall -Werror -o $# $^ -g -O0 -lboost_system -lboost_thread -lboost_signals -lpthread
And invoke it with
./strand 127.0.0.1:6767
I have a responding script sitting there doing (basically)
netcat -l -p 6767 -e rev
One other thing to note: the write buffer never seems to actually be sent/flushed until I interrupt the strand tester (client side). This happens regardless how large I make data... This is probably due to a step I'm missing?
Edit:
Tested identical on
ubuntu meerkat, gcc 4.4.5, boost 1.42.0
debian sid, gcc 4.5.2-8, boost 1.46.1

Can't display images on a gtkmm-based gnome-panel applet

I ran into troubles trying to create a gnome-panel applet with gtkmm. I dealt with most of them, but I'm now kind of blocked.
Quick summary : I tried libpanelappletmm, but every program (even the examples supplied in the source code) segfaults when I try to add the applet in my panel.
So I now use the C library (libpanel-applet). First I looked for a way to wrap the PanelApplet Gobject in a gtkmm C++-object, for example a Gtk::EventBox (PanelApplet inherits from GtkEventBox). I tried to cast it, but Glibmm kept throwing a warning ("Failed to wrap object 'PanelApplet'").
So I created a class "Info", inheriting from Gtk::HBox. In my main.cpp file I declare an instance of it, get the underlying GTK object (gobj method), and use the GTK+ functions to add it into the PanelApplet.
Here's my main.cpp.
#include <iostream>
#include <gtkmm.h>
#include <panel-applet.h>
#include "Info.hpp"
static void manage_timeboxes(BonoboUIComponent *uic, void *applet, const char* data) {
std::cout << "manage" << std::endl;
}
static gboolean getApplet(PanelApplet *applet, const gchar *iid, gpointer data) {
/*
if(iid != "OAFIID:TimeboxingApplet")
return false;
*/
Glib::init();
Gtk::Widget* content = new Info();
gtk_container_add(GTK_CONTAINER(applet), content->gobj());
static const char menu_xml[] =
"<popup name=\"button3\">\n"
" <menuitem name=\"Manage\" "
" verb=\"manage_timeboxes\" "
" _label=\"_GĂ©rer l'emploi du temps\"\n"
" pixtype=\"stock\" "
" pixname=\"gtk-properties\"/>\n"
"</popup>\n";
static const BonoboUIVerb linked_verbs[] = {
BONOBO_UI_VERB ("manage_timeboxes", manage_timeboxes),
BONOBO_UI_VERB_END
};
panel_applet_setup_menu(applet, menu_xml, linked_verbs, data);
gtk_widget_show_all(GTK_WIDGET(applet));
return true;
}
PANEL_APPLET_BONOBO_FACTORY (
"OAFIID:TimeboxingApplet_Factory",
PANEL_TYPE_APPLET,
"Timeboxing",
"0.0",
getApplet,
NULL)
It works fine if I add labels or buttons in my Info object.
But then I tried to add an icon.
My first try was adding a Gtk::Image as a property of Info.
Info.hpp
#ifndef TIMEBOXING_INFO_H
#define TIMEBOXING_INFO_H
#include <gtkmm/box.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
class Info : public Gtk::HBox {
public:
Info();
virtual ~Info(){};
protected:
Gtk::Image icon;
Gtk::Label info;
};
#endif
Info.cpp
#include "Info.hpp"
#include <gtkmm/image.h>
#include <gtkmm/label.h>
Info::Info() : icon("/home/bastien/programmation/timeboxing-applet/icons/clock-24.png"), info("<b>En cours</b>") {
info.set_use_markup();
pack_start(icon);
pack_start(info);
show_all_children();
}
When I try to add the applet, I get this error and the program aborts :
glibmm:ERROR:objectbase.cc:78:void Glib::ObjectBase::initialize(GObject*): assertion failed: (gobject_ == castitem)
I commented "Gtk::Image icon" from Info.hpp, and I modified my constructor like this :
Info::Info() : info("<b>En cours</b>") {
info.set_use_markup();
Gtk::Image icon("/home/bastien/programmation/timeboxing-applet/icons/clock-24.png");
pack_start(icon);
pack_start(info);
show_all_children();
}
I'm not getting the Glibmm error anymore, but the image isn't displayed. I tried with another file, with an icon from the stock, and even with a Gdk::Pixbuf.
Thank you in advance !
Well, strangely enough, it works if I create a pointer to Gtk::Image.
If anyone has an explanation, it would be great !
Edit : apparently, I had to call Gtk::Main::init_gtkmm_internals. My wrapping troubles went away. I can wrap PanelApplet too, but if I use the resulting Gtk::EventBox* it doesn't display anything.

Resources