使用静态Qt构建在Linux上部署Qt5应用程序

时间:2018-07-09 08:32:04

标签: c++ qt qt5

我已经使用以下命令在ubuntu上构建并安装了Qt5.11的静态版本:

<?php
require('fpdf181/fpdf.php');


if(isset($_POST['submit'])){
    $id_appartamenti = $_POST['id_appartamenti'];
    $taglio = $_POST['taglio'];
    $style = $_POST['style'];
    $piano = $_POST['piano'];
    $mq = $_POST['mq'];
    $mood = $_POST['mood'];
    $finiture = $_POST['finiture'];
    $prezzo = $_POST['prezzo'];
    $nome = $_POST['nome'];
    $email = $_POST['email'];
    
    //A4 width: 219 mm
    //default margin: 10mm each side
    //writable horizontal: 219 - (10*2)=189mm
    $pdf = new FPDF('p', 'mm', 'A4');
    
    $pdf->AddPage();

    //set font to arial, bold, 14pt
    $pdf->SetFont('Arial','B', 14);

    //cell(width, height, text, border, endline, align)
    
    //titolo
    $pdf->Image('../images/favicon-outline-grigia.png',95, 2, 20, 20,0,1);    
    $pdf->Cell(0,30,'Buongiorno '.$nome.', ecco la configurazione del tuo '.$taglio.' '.$style.':',0,1,'C');
    
    //img
    $pdf->Cell(0,120,'',0,1);
    $pdf->Image('../images/bilocale1.jpg',20, 40, 160, 120,0,1);

    //corpo   
    //set font to arial, reg, 12pt
    $pdf->SetFont('Arial','', 10); 

    
    //riga 1
    $pdf->SetFillColor(230,230,230);
    $pdf->Cell(130,8,'ID appartamento:',0,0,'L', true);
    $pdf->Cell(59,8,''.$id_appartamenti.'',0,1,'L', true);//end of line
    
    //riga 2
    $pdf->SetFillColor(255,255,255);
    $pdf->Cell(130,8,'Piano:',0,0,'L', true);
    $pdf->Cell(59,8,''.$piano.'',0,1,'L', true);//end of line
    
    //riga 3
    $pdf->SetFillColor(230,230,230);
    $pdf->Cell(130,8,'Mq:',0,0,'L', true);
    $pdf->Cell(59,8,''.$mq.'',0,1,'L', true);//end of line  
    
    //riga 4
    $pdf->SetFillColor(255,255,255);
    $pdf->Cell(130,8,'Mood:',0,0,'L', true);
    $pdf->Cell(59,8,''.$mood.'',0,1,'L', true);//end of line  
    
    //riga 5
    $pdf->SetFillColor(230,230,230);
    $pdf->Cell(130,8,'Finiture:',0,0,'L', true);
    $pdf->Cell(59,8,''.$finiture.'',0,1,'L', true);//end of line
    
    //riga 5
    //set font to arial, bold, 14pt
    $pdf->SetFont('Arial','B', 20);    
    $pdf->SetTextColor(234, 103 , 12);
    $pdf->SetFillColor(255,255,255);
    $pdf->Cell(130,50,'',0,0,'R', true);
    $pdf->Cell(59,50,'Totale: '.$prezzo.' Euro',0,1,'R', true);//end of line  
    

    
////////////////////////////////////////////////////////////prima mail al cliente
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
    
    
      // email stuff (change data below)
    $to = "$email"; 
    $from = "noreply@tecmasolutions.com"; 
    $subject = "Tecma - la tua configurazione"; 
    $message = "<p>Buongiorno $nome, in allegato potrai trovare le tua configurazione</p>";

    // a random hash will be necessary to send mixed content
    $separator = md5(time());

    // carriage return type (we use a PHP end of line constant)
    $eol = PHP_EOL;

    // attachment name
    $filename = "$id_appartamenti.pdf";

    // encode data (puts attachment in proper format)
    $pdfdoc = $pdf->Output("", "S");
    $attachment = chunk_split(base64_encode($pdfdoc));

    // main header (multipart mandatory)
    $headers = "From: ".$from.$eol;
    $headers .= "MIME-Version: 1.0".$eol;
    $headers .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;

    //NOTICE I changed $headers to $body!!

    $body .= "Content-Transfer-Encoding: 7bit".$eol;
    $body .= "This is a MIME encoded message.".$eol; //had one more .$eol

    // message
    $body .= "--".$separator.$eol;
    $body .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
    $body .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
    $body .= $message.$eol; //had one more .$eol

    // attachment
    $body .= "--".$separator.$eol;
    $body .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
    $body .= "Content-Transfer-Encoding: base64".$eol;
    $body .= "Content-Disposition: attachment".$eol.$eol;
    $body .= $attachment.$eol;
    $body .= "--".$separator."--";
  

  mail($to, $subject, $body, $headers);       

////////////////////////////////////////////////////////////seconda mail al cliente
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////    
    
    
       // email stuff (change data below)
    $to2 = "s.zanetti@tecmasolutions.com"; 
    $from2 = "$email"; 
    $subject2 = "Tecma - richiesta info per $id_appartamenti "; 
    $message2 = "<p>Una nuova richiesta da parte di $nome, per l'appartamento $id_appartamenti.</p>";

    // a random hash will be necessary to send mixed content
    $separator = md5(time());

    // carriage return type (we use a PHP end of line constant)
    $eol = PHP_EOL;

    // attachment name
    $filename = "$id_appartamenti.pdf";

    // encode data (puts attachment in proper format)
    $pdfdoc = $pdf->Output("", "S");
    $attachment = chunk_split(base64_encode($pdfdoc));

    // main header (multipart mandatory)
    $headers2 = "From: ".$from.$eol;
    $headers2 .= "MIME-Version: 1.0".$eol;
    $headers2 .= "Content-Type: multipart/mixed; boundary=\"".$separator."\"".$eol.$eol;

    //NOTICE I changed $headers to $body!!

    $body2 .= "Content-Transfer-Encoding: 7bit".$eol;
    $body2 .= "This is a MIME encoded message.".$eol; //had one more .$eol

    // message
    $body2 .= "--".$separator.$eol;
    $body2 .= "Content-Type: text/html; charset=\"iso-8859-1\"".$eol;
    $body2 .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
    $body2 .= $message.$eol; //had one more .$eol

    // attachment
    $body2 .= "--".$separator.$eol;
    $body2 .= "Content-Type: application/octet-stream; name=\"".$filename."\"".$eol;
    $body2 .= "Content-Transfer-Encoding: base64".$eol;
    $body2 .= "Content-Disposition: attachment".$eol.$eol;
    $body2 .= $attachment.$eol;
    $body2 .= "--".$separator."--";   
    
    
 
    
/////////////////////////////////send message
/////////////////////////////////    
/////////////////////////////////    
/////////////////////////////////


    mail($to2, $subject2, $body2, $headers2);
    

}
header('Location: ../thank-you.html');
?>

构建成功完成。

然后我尝试将我的项目与此版本链接,但失败。这是输出的最后几行:

  

编译输出(Qt-Creator)

make distclean; ./configure 
-static -release -ltcg -optimize-size -no-pch -prefix 
"/opt/qt/511-static-release" -skip webengine -nomake tools 
-nomake tests -nomake examples; make -j 8; make install;
  

链接器输出

...

../src/config/config_dialog.h -o moc_config_dialog.cpp
g++ -c -pipe -std=c++11 -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC - 
DQT_DEPRECATED_WARNINGS -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB 
-DQT_CORE_LIB -I../../my-gui-qt -I. -I../src/view/ -I./model - 
I/opt/qt/511-static-release/include -I/opt/qt/511-static- 
release/include/QtWidgets -I/opt/qt/511-static-release/include/QtGui - 
I/opt/qt/511-static-release/include/QtNetwork -I/opt/qt/511-static- 
release/include/QtCore -I. -isystem /usr/include/libdrm -I. - 
I/opt/qt/511-static-release/mkspecs/linux-g++ -o moc_config_dialog.o 
moc_config_dialog.cpp
  

链接器警告

../../ include / QtCore /../../ src / corelib / kernel / qobjectdefs_impl.h:163:46:警告:类型“ struct Function”违反了一个定义规则[-Wodr] .moc / qcolordialog.moc:111:57:注意:另一个翻译单元中定义了其他类型

dialogs / qcolordialog.cpp:1738:41:注意:相应定义的第一个区别是字段“ __pfn”

.moc / qcolordialog.moc:111:56:注意:在另一个翻译单元中定义了一个名称相同但类型不同的字段 lto1:注意:参数1中的类型不匹配 dialogs / qcolordialog.cpp:179:7:注意:匿名命名空间中定义的“ struct QWellArray”类型不能与“ struct QWellArray”类型

匹配

dialogs / qcolordialog.cpp:180:1:注意:另一个翻译单元中匿名名称空间中定义的不兼容类型 qicohandler.cpp:95:3:警告:类型“ struct BMP_INFOHDR”违反了一个定义规则[-Wodr]

... 以及其他一些类似的警告。

该链接确实完成并生成了可执行文件,但它不可运行。我可以看到文件在那里:

 g++ -Wl,-Bdynamic -lGL -static -fPIC -o my-gui-qt main.o 
 mainwindow.o task_status_delegate.o my-gui-qt_plugin_import.o  
 qrc_resources.o moc_mainwindow.o moc_task_table_view.o 
 moc_task_table_model.o moc_config_dialog.o 
 -L/opt/qt/511-static-release/lib -lQt5OpenGL -L/usr/lib/x86_64-linux-
 gnu -L/opt/qt/511-static-release/plugins/platforms 
 -lqxcb -L/opt/qt/511-static--release/plugins/xcbglintegrations 
 -lqxcb-glx-integration -lQt5XcbQpa -lQt5ServiceSupport 
 -lQt5ThemeSupport -lQt5EventDispatcherSupport 
 -lQt5FontDatabaseSupport -lfontconfig -lfreetype -lQt5GlxSupport - 
 lXext -lQt5EdidSupport -lxcb-glx -lX11-xcb -lX11 -lXi -lSM -lICE - 
 lXrender -lxcb-static -lxcb -L/opt/qt/511-static- 
 release/plugins/imageformats -lqgif -lqicns -lqico -lqjpeg -lqtga - 
 lqtiff -lqwbmp -lqwebp -L/opt/qt/511-static-release/plugins/bearer - 
 lqconnmanbearer -lqgenericbearer -lqnmbearer -lQt5DBus -lQt5Widgets - 
 lQt5Gui -lpng12 -lqtharfbuzz -lQt5Network -lQt5Core -lm -lz -licui18n 
 -licuuc -licudata -lqtpcre2 -ldl -lgthread-2.0 -lglib-2.0 -lGL - 
 lpthread 

但是尝试运行它会出现错误:

$ file my-gui-qt

$ my-gui-qt: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), 
dynamically linked, interpreter /lib/ld64.so.1, for GNU/Linux 2.6.32, 
BuildID[sha1]=0e22025dfc5f4bf4dbba598a6f692607303b68c, not stripped

编辑:我能够使用相同的Qt 5.11静态构建和使用相同库的琐碎(小巧)Qt应用程序来重现此问题。该应用程序将编译并正常运行,直到我添加与上述my-gui-qt应用程序相同的QMAKE标志:

me@me-Inspiron-15-7000-Gaming:~/code/my-gui-qt/build-static$ ./my-gui- 
qt 
bash: ./my-gui-qt: No such file or directory

原因是将不同的解释器链接到exe:

因此,没有上面的QMAKE_LFLAGS

QMAKE_LFLAGS += -Wl,-Bdynamic -lGL -static

礼物:

$file TestProject*

运行正常。但是带有标志,它给出:

TestProject: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), 
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for 
GNU/Linux 2.6.32, 
BuildID[sha1]=993c09e6977c18772569a5a6ecb452c03a884f2d, not stripped

并且不运行(bash ::无此类文件或目录)。似乎设置-Bdynamic标志将使gcc回退到Ubuntu16.04中不存在的通用Unix gcc解释器/lib/lib64.so.1。不确定如何解决此问题?已尝试 -Wl,-dynamic-linker = / lib / ld-lsb.so.2 ,但未成功。

1 个答案:

答案 0 :(得分:1)

因此,原来这个问题已经得到解决,我只是看不到它。

在将Qt应用程序链接到静态版本的Qt时,如果某些组件(libGL.so)可以动态链接(即QMAKE_LFLAGS + = -Wl,-Bdynamic,--lGL -static),则ELF解释程序可能会解析为它的默认值(因为上面的命令将覆盖特定的解释器路径),因此,要恢复它,您应该再次指定它(如许多其他人所说的那样):

QMAKE_LFLAGS += -Wl,-dynamic-linker=/lib64/ld-linux-x86-64.so.2  

应用程序现在可以正常运行。当使用这些标志的组合时,仍然会保留多个定义警告(即使对于琐碎的Qt应用程序)。