Including edk2-libc in efi shell application - libc

How would one approach adding support for https://github.com/tianocore/edk2-libc, say I want to include stdio and use printf in my edk2 application? I followed StdLib/Readme.txt, and am able to successfully build examples in the AppPkg, however, when I try to add StdLib to my project I get errors like these:
LibString.lib(Searching.obj) : error LNK2005: strspn already defined in LibString.lib(Searching.obj)
LibCtype.lib(CClass.obj) : error LNK2005: isspace already defined in LibCtype.lib(CClass.obj)
(...)
LibC.lib(Main.obj) : error LNK2001: unresolved external symbol main
I do have the boilerplate (!include StdLib/StdLib.inc) added to my dsc file and in inf, I have StdLib.dec added to Packages and LibC and LibStdio added to LibraryClasses. I am using VS2017 toolchain for compilation and am using edk2-stable202108 release.

I was able to achieve this using below configuration for Hello Application of AppPkg.
Hello.inf
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = Hello
FILE_GUID = a912f198-7f0e-4803-b908-b757b806ec83
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
Hello.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec
[LibraryClasses]
UefiLib
ShellCEntryLib
BaseLib
BaseMemoryLib
MemoryAllocationLib
LibStdLib
LibStdio
LibString
DevConsole
Hello.c
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <stdio.h>
int
main (
IN int Argc,
IN char **Argv
)
{
printf("Hello, world!\n");
return 0;
}
What I have understood is that LibC has ShellAppMain() defined in it which internally calls extern main(). So You need to provide definition of main() in your source just like I did in Hello.c

Related

Qt PostgreSQL linker error when trying to add database

I'm trying to set a connection to postgre database, but having linker errors.
.pro file:
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
CONFIG += sql
DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
unix|win32: LIBS += -L$$PWD/../../PostgreSQL/12/lib/ -llibpq
INCLUDEPATH += $$PWD/../../PostgreSQL/12/include
DEPENDPATH += $$PWD/../../PostgreSQL/12/include
win32:!win32-g++: PRE_TARGETDEPS += $$PWD/../../PostgreSQL/12/lib/libpq.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$PWD/../../PostgreSQL/12/lib/liblibpq.a
.cpp file:
#include <QCoreApplication>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSql>
#include <QtSql/QSqlDriver>
#include <QTextStream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSqlDatabase mDB=QSqlDatabase::addDatabase("QPSQL");
return a.exec();
}
It's just that. I'm not even trying to connect yet.
Errors are:
main.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl QSqlDatabase::~QSqlDatabase(void)" (__imp_??1QSqlDatabase##QEAA#XZ) referenced in function main
main.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: static class QSqlDatabase __cdecl QSqlDatabase::addDatabase(class QString const &,class QString const &)" (__imp_?addDatabase#QSqlDatabase##SA?AV1#AEBVQString##0#Z) referenced in function main
main.obj:-1: error: LNK2001: unresolved external symbol "__declspec(dllimport) public: static char const * const QSqlDatabase::defaultConnection" (__imp_?defaultConnection#QSqlDatabase##2PEBDEB)
Postge is 64bit for Windows, compiler chosen for this application is also 64 MSVC2019 64bit. Please help.
Problem was in .pro file. It should be:
QT += sql
and not:
CONFIG += sql

Swig -> Perl5 : Error compiling simplest SWIG-Module with VC15

I have a quite simple Swig Module for Demo purposes but can't get the wrapper/stub to get compiled.
Swigtest.h:
#pragma once
class Swigtest {
public:
Swigtest() {};
int func1(int param1);
};
Swigtest.cpp
#include "Swigtest.h"
int Swigtest::func1(int param1)
{
return param1 + 1;
}
Swigtest.i
%module Swigtest
%{
#include "Swigtest.h"
%}
%include "Swigtest.h"
The wrapper ist generated with swig.exe -c++ -perl5 Swigtest.i and then the compilation of the wrapper Swigtest_wrap.cxx fails with the following first error:
[path_to_perl_lib]\lib\core\win32.h(371): error C2061: syntax error: identifier 'STRLEN'
I'm using VisualStudio 2015 Toolset (acutally running on VS17) with Target Platform Version 8.1 and Swigwin 3.0.12.
Thank's for your help!

WiringPi's LCD Library - undefined reference to `lcdInit'

Trying to compile a very simple program for testing wiringpi's library for the hd44780 lcd controller:
#include <iostream>
#include <wiringPi.h>
#include <lcd.h>
...
int main()
{
init_wiringpi;
fd = lcdInit(2, 16, 4, 11,10 , 0,1,2,3,0,0,0,0) ;
...
return = 0;
}
Build Messages
LCD_first.cpp - undefined reference to `lcdInit'
LCD_first.cpp - undefined reference to `lcdPosition'
LCD_first.cpp - undefined reference to `lcdPuts'
Ok i just had to add lcd.o to the linked libraries list in Code::Blocks (settings/compiler/Linker settings/Link libraries >> /home/pi/wiringPi/devLib/lcd.o).

Attempt to embed Perl in C on Windows

I am trying to run the following example from
Deploy a Perl Application on Windows
with a simple "Hello.pl" (just prints "Hello" to STDOUT).
It fails. The .exe file is created but does not produce any output.
Probably this is my basic misunderstanding. Could you please point me in the right direction? Btw. the "lib folder containing all dependencies" in the project folder is empty since there are no modules in the "hello.pl". Is this a correct assumption?
Thank you very much!
The hello.c file:
#include <EXTERN.h>
#include <perl.h>
EXTERN_C void xs_init (pTHX);
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void boot_Win32CORE (pTHX_ CV* cv);
EXTERN_C void
xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;
/* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
newXS("Win32CORE::bootstrap", boot_Win32CORE, file);
}
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
int main(int argc, char **argv, char **env)
{
argv[1] = "-Ilib";
argv[2] = "hello.pl";
PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct(my_perl);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_parse(my_perl, NULL, argc, argv, (char **)NULL);
perl_run(my_perl);
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
}
The perl file to build the compiler command:
#!/perl
use strict;
use warnings FATAL => qw(all);
use ExtUtils::Embed;
print "\nBuilding Hello\n";
my $gcc_cmd = join( ' ' , 'C:\Perl_516_portable\c\bin\gcc -Wall -mwindows -o K:\Scripts\Embed\Hello_3\hello K:\Scripts\Embed\Hello_3\hello.c',
&ccopts, &ldopts );
print STDOUT $gcc_cmd , "\n";
system( $gcc_cmd );
The output:
----------------------------------------------
Perl executable: C:\Perl_516_portable\perl\bin\perl.exe
Perl version : 5.16.3 / MSWin32-x86-multi-thread
C:\Perl_516_portable>perl K:\Scripts\Embed\Hello_3\building_3.pl
Building Hello
C:\Perl_516_portable\c\bin\gcc -Wall -mwindows -o K:\Scripts\Embed\Hello_3\hello K:\Scripts\Embed\Hello_3\hello.c -s -O2 -DWIN32 -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -mms-bitfields -I"C:\Perl_516_portable\perl\lib\CORE" -s -L"C:\Perl_516_portable\perl\lib\CORE" -L"C:\Perl_516_portable\c\lib" C:\Perl_516_portable\perl\lib\CORE\libperl516.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libmoldname.a C:Perl_516_portable\c\i686-w64-mingw32\lib\libkernel32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libuser32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libgdi32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libwinspool.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libcomdlg32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libadvapi32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libshell32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libole32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\liboleaut32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libnetapi32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libuuid.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libws2_32.a C:Perl_516_portable\c\i686-w64-mingw32\lib\libmpr.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libwinmm.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libversion.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libodbc32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libodbccp32.a C:\Perl_516_portable\c\i686-w64-mingw32\lib\libcomctl32.a
In file included from C:\Perl_516_portable\perl\lib\CORE/sys/socket.h:180:0,
from C:\Perl_516_portable\perl\lib\CORE/win32.h:356,
from C:\Perl_516_portable\perl\lib\CORE/win32thread.h:4,
from C:\Perl_516_portable\perl\lib\CORE/perl.h:2834,
from K:\Scripts\Embed\Hello_3\hello.c:2:
C:\Perl_516_portable\perl\lib\CORE/win32.h:361:26: warning: "/*" within comment [-Wcomment]
C:\Perl_516_portable\perl\lib\CORE/win32.h:362:33: warning: "/*" within comment [-Wcomment]
In file included from C:\Perl_516_portable\perl\lib\CORE/win32thread.h:4:0,
from C:\Perl_516_portable\perl\lib\CORE/perl.h:2834,
from K:\Scripts\Embed\Hello_3\hello.c:2:
C:\Perl_516_portable\perl\lib\CORE/win32.h:361:26: warning: "/*" within comment [-Wcomment]
C:\Perl_516_portable\perl\lib\CORE/win32.h:362:33: warning: "/*" within comment [-Wcomment]
K:\Scripts\Embed\Hello_3\hello.c: In function 'main':
K:\Scripts\Embed\Hello_3\hello.c:37:1: warning: control reaches end of non-void function [-Wreturn-type]
It will not work if you are in a different path than your script and c files. Remove the absolute paths K:\Scripts\Embed\Hello_3\
The "lib folder containing all dependencies" in the project folder is empty since there are no modules in the "hello.pl". Is this a correct assumption?
If hello.pl does not use any libs, yes.
int main(int argc, char **argv, char **env)
{
argv[1] = "-Ilib";
argv[2] = "hello.pl";
...
This will only work if argc is 2, i.e. you provided 2 args to your hello.exe.
You rather need to check argc and extend argv if < 2, and set argc to 2 if < 2.
Step into the executable with gdb and see what's going wrong. Compile with -g then.
In the long term, the established solution is to use PAR::Dist, or one of the commercial packers. Using the real compiler perlcc on Windows is a bit tricky.

g++ problem with -l option and PostgreSQL

I've written simple program.
Here a code:
#include <iostream>
#include <stdio.h>
#include <D:\Program Files\PostgreSQL\8.4\include\libpq-fe.h>
#include <string>
using namespace std;
int main()
{
PGconn *conn;
PGresult *res;
int rec_count;
int row;
int col;
cout << "ble ble: " << 8 << endl;
conn = PQconnectdb("dbname=db_pm host=localhost user=postgres password=postgres");
if (PQstatus(conn) == CONNECTION_BAD) {
puts("We were unable to connect to the database");
exit(0);
}
}
I'm trying to connect with PostgreSQL.
I compile this code with following command:
gcc -I/"d:\Program Files\PostgreSQL\" -L/"d:\Program Files\PostgreSQL\8.4\lib\" -lpq -o firstcpp.o firstcpp.cpp
This command is from following site:
http://www.mkyong.com/database/how-to-building-postgresql-libpq-programs/
And when I compile it I get following error:
/cygnus/cygwin-b20/H-i586-cygwin32/i586-cygwin32/bin/ld: cannot open -lpq: No such file or directory
collect2: ld returned 1 exit status
Does anyone help me?
Difek
You can try using forward slashes instead of backward slashes. And I have no idea about the first forward slash. Isn't it meant to be inside the quotes ? Eg -I"/d:/Program Files/PostgreSQL/"
Anyway, if you are using the gcc from cygwin, you could also try
-I"/cygdrive/d/Program Files/PostgreSQL"
And I'd do the same with that include (libpq-fe) - though apparently that is working, the error is in the linker.