Shared Library won't compile, *.a file missing - linux

I'm trying to make a shared library, in Linux, which is a *.so. My DMD version is 2, latest. I'm just trying yo compile a simple empty shared library, with the code that Mono-D(plugin for MonoDevelop) creates. When I try to compile it, it tells me to check the build log, this is what's in the build log:
Building Solution: QScr (Debug)
Building: QScr (Debug)
Performing main compilation...
Current dictionary: /home/nafees/Desktop/Projects/QScr/QScr
dmd -debug -gc "myclass.d" "dllmain.d" "-I/usr/include/dmd" "-L/IMPLIB:/home/nafees/Desktop/Projects/QScr/QScr/bin/Debug/libQScr.a" "-odobj/Debug" "-of/home/nafees/Desktop/Projects/QScr/QScr/bin/Debug/libQScr.so" -w -vcolumns
/usr/bin/ld: cannot find /IMPLIB:/home/nafees/Desktop/Projects/QScr/QScr/bin/Debug/libQScr.a: No such file or directory
collect2: error: ld returned 1 exit status
--- errorlevel 1
Exit code 1
Build complete -- 1 error, 0 warnings
---------------------- Done ----------------------
Build: 1 error, 0 warnings
This is what dllmain contains:
module dllmain;
And in myclass.d:
module myclass;
class MyClass
{
//TODO: Enter class code here
}
export:
extern(D):
MyClass createMyClass()
{
return new MyClass();
}
I have no idea what is that a file, I'm still fairly new to D, and Linux.
How do I get it to compile? And could someone explain to me what is an .a file?
EDIT: No, it's not a duplicate, I'm trying to compile, while that question is about loading libraries.
EDIT2: I checked the directory, the .a file doesn't exist.

/usr/bin/ld: cannot find /IMPLIB:/home/nafees/Desktop/Projects/QScr/QScr/bin/Debug/libQScr.a: No such file or directory
/IMPLIB is a Windows linker switch. Your IDE is misconfigured (or just buggy).
Try changing the project settings in the IDE or filing a bug against the IDE.

Few things.
extern(D) would not be needed for free functions since it is default
You don't need createMyClass function at all, new will work fine
-shared must be passed to dmd for it to create a shared library
In case you didn't know, you will be passing the files in the shared library as import files when compiling the host binary.

Related

Why does/can my build access sysctl on Linux?

I inherited a C++ code with a dependency to OpenMPI that I want to delegate to Conan and CMake, and the automated build has a strange (to me at least) behavior related to sysctl that I want to understand.
How I tried to do it
I declared the required dependencies in my root CMakeLists.txt:
Note: I added the full list of requirements because I also suspect that some of them may be in conflict? That happened before with boost, that forced me to set explicitly zlib (if i remember correctly).
# stuff ...
conan_cmake_configure(
REQUIRES
zlib/1.2.12
mp-units/0.7.0
boost/1.79.0
openmpi/4.1.0
gsl/2.7
cspice/0067
GENERATORS
cmake
# that is required for cspice
CMakeDeps
CMakeToolchain
)
# more stuff ...
and then in the application CmakeLists.txt I find, include and link the executable to the required libraries:
add_executable(spock main.cpp)
find_package(cspice REQUIRED)
find_package(openmpi REQUIRED)
target_include_directories(
spock PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
openmpi_INCLUDE_DIRS
cspice_INCLUDE_DIRS
)
target_link_libraries(spock
CONAN_PKG::boost
CONAN_PKG::mp-units
openmpi::openmpi
cspice::cspice
)
# We need C++ 20 activated with the concepts library
target_compile_features(spock PUBLIC cxx_std_20)
Problem: undefined reference to sysctl ... on my local system only.
Building on my local machine with CMake 3.23.2 results in the following error message:
Consolidate compiler generated dependencies of target spock
[ 25%] Building CXX object src/CMakeFiles/spock.dir/main.cpp.o
^[[A^[[A[ 50%] Linking CXX executable ../bin/spock
/usr/bin/ld: /home/becheler/.conan/data/openmpi/4.1.0/_/_/package/8f7048d1bf6fc2a7985eb087c34e69a5e64f6c86/lib/libopen-pal.a(evutil_rand.o): in function `arc4_stir.isra.0':
evutil_rand.c:(.text+0x3d2): undefined reference to `sysctl'
collect2: error: ld returned 1 exit status
gmake[2]: *** [src/CMakeFiles/spock.dir/build.make:146: bin/spock] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:135: src/CMakeFiles/spock.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2
However, the same build on Github workflows on Ubuntu 20.04 works. What is weird. The only difference before apart the distribution version is that github wokflows use higher privileges than me on local (I believe?).
What I tried so far
I've been trying to read about what this sysctlreference is. And I found conflicting information:
Frrom this man page:
The sysctl() function retrieves system information and allows processes with appropriate privileges to set system information.
this similar SO question came to the conclusion that
Linux does not support this function (other OS like MacOS or FreeBSD support it)
A comment from the same post concludes that in Linux,
these details can be obtained by reading the kernel-provided
pseudofiles /proc/cpuinfo and /proc/meminfo
So here is my question: why does it compile at all on the remote server if this command is not supposed to exist on the OS used?

undefined reference to `__gcov_exit'?

while I am building glibc library using yocto project it is giving
error: missing attribute ((constructor)) support??
after adding the coverage flags:
TARGET_CFLAGS += "-fprofile-arcs -ftest-coverage"
TARGET_LDFLAGS += "-lgcov -fprofile-arcs -ftest-coverage"
still, I am getting an error for glibc.
Please find the link of config log file : https://drive.google.com/file/d/14tiQJ8JIFE_tDWt3H9tS8zBBQROcZDNa/view
It is not working even after adding the following line in conf/local.conf :
EXTRA_OECONF = "libc_cv_ctors_header=yes"
Even i tried this
EXTRA_OECONF_append = "libc_cv_ctors_header=yes"
please find the config log file generated during compilation : https://drive.google.com/open?id=1kxTu8pt7h_9ty55OywP9Ilmmp04T61Rr
So, How to resolve this error?
Log file error Point
poky-linux/gcc/i586-poky-linux/8.2.0/ld: /tmp/ccxetEc1.o: in function `_GLOBAL__sub_D_00100_1__start':
conftest.c:(.text.exit+0x40): undefined reference to `__gcov_exit'<br>
collect2: error: ld returned 1 exit status<br>
configure:5682: $? = 1<br>
configure:5702: error: missing __attribute__ ((constructor)) support??
You are trying to build glibc with -fprofile-arcs -ftest-coverage in CFLAGS. That will not work. The errors you see are a result of these incorrect compiler flags.
A profiling glibc requires fairly substantial changes throughout the library and needs to be created by building with --enable-profile (which is not the default).
I had this error while I tried to enable coverage on a C project using a C++ test harness (CppUTest). Build system was handled by CMake.
Compilers and gcov were aligned on the same version (gcc --version, g++ --version and gcov --version gave the same version) but it seems that my build system was generated with a gcc 5 (resulting to an additional included directory by the linker: usr/lib/gcc/x86_64-linux-gnu/5). I clean the build tree and generated it again thanks to CMake which fixed the error.

Getting "undefined reference to" when using the lib for ARM, but not when compiling it

For one of my Qt Embedded projects I'm using a external Qt lib called SMTPEmail. This lib needs to be compiled before being included into a project, something that I managed to do successfully both for Qt 4.8 ARM and for Desktop.
The problem I'm getting is that when I include the headers into my project and include the library in the .pro, the linker gives me
(path_to_libs)/libSMTPEmail.so: undefined reference to `QSslSocket::connectToHostEncrypted(QString const&, unsigned short, QFlags<QIODevice::OpenModeFlag>)'
(path_to_libs)/libSMTPEmail.so: undefined reference to `QSslSocket::QSslSocket(QObject*)'
collect2: ld returned 1 exit status
make: *** [re8k_interface-tgt] Error 1
but only for compiling for ARM. IOW compiling the lib for both ARM and Desktop goes OK, compiling the project for Desktop using the lib goes OK but compiling it for ARM using the lib goes wrong.
Following this forum thread I suspected this could be due to missing the link to the library file of openssl (the project points to different lib folders when compiling for different environments). So I searched for all "openssl" related files inside the compiler for ARM (arm-arago-linux-gnueabi) and included in the same folder where the .so is located; same error. I then suspected the lib itself had other dependencies which were not in the path_to_libs, so I did a readelf -d libSMTPEmail.so and later in the .so.1 and readelf did return some lib dependencies that were not inside the same folder of the library. I then copied all such dependencies to the folder and got no success either.
So what could be happening? All dependencies known by me were put in place and I still get the error only for the situation where the lib is included by another project compiled for ARM.
You need to point your QMake where your libs and header file is in your .pro file;
So find where your library is assume /usr/local/include then ;
INCLUDEPATH += /usr/local/include
Add which libs you will use;
LIBS += -lSMTPEmail
You can check my answer here;
Two things stand out for me in your question:
1.
undefined reference to
This error message means that there was an error in the linking step of compilation. This occurs when you include a header to a function/class/variable but don't have the definition included in your own sources, or you do not link in a static library that does.
Searching for dependencies in libraries that are already compiled (.dll or .so) is too late, the compiler is looking for a static link, not a dynamic link.
2.
compiling the lib for both ARM and Desktop goes OK, compiling the
project for Desktop using the lib goes OK but compiling it for ARM
using the lib goes wrong.
This suggests that you are using conditional compilation in your .pro file that does a "both" compilation, a "desktop only" compilation and a "ARM only" compilation. If this is correct, you need to examine your compilation instructions for your "ARM only" compilation.
The error message itself refers to you using two functions from the QSslStock class. These are part of the QtNetwork module so you should have the following in your .pro file in order for the necessary links to be formed.
Qt += network

How to use gtkd on linux

I am trying to compile a hello world program using the gtkd library.
I am using the dmd compiler (installed into my ~/ directory) and I have already checked that the compiler works flawlessly.
Just in case, here is my source code:
//pragma(lib, "gtkd");
//pragma(lib, "dl");
import gtk.MainWindow;
import gtk.Label;
import gtk.Main;
void main(string[] args)
{
Main.init(args);
MainWindow win = new MainWindow("Hello World");
win.setDefaultSize(200, 100);
win.add(new Label("Hello World"));
win.showAll();
Main.run();
}
The pragmas are commented out, because (if I understand this correctly) they do nothing more than the -L-l flags, nor did they get me any closer to a solution.
Anyways, after I save the file, I run:
dmd hello.d -L-lgtkd -L-ldl
and get the following error:
/usr/bin/ld: cannot find -lgtkd
collect2: error: ld returned 1 exit status
--- errorlevel 1
I already copied libgtkd-3.a, libgtkdgl-3.a and libgtkdsv-3.a into /usr/lib, but the output of the terminal remained the same.
I understand that the linker can't find my files, but I don't know how else I can help him do so.
For further info on my installation, I have set up everything exactly as in this post.
Not sure if it matters, but my computer is running crunchbang, a distro based on debian wheezy.
Thanks in advance,
R
dmd hello.d -L-lgtkd -L-ldl
this try to find libgtkd.a but you does not have libgtkd.a, you have libgtkd-3.a so you must use:
dmd hello.d -L-lgtkd-3 -L-ldl

crt1.o: In function `_start': - undefined reference to `main' in Linux

I am porting an application from Solaris to Linux
The object files which are linked do not have a main() defined. But compilation and linking is done properly in Solaris and executable is generated. In Linux I get this error
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
My problem is, I cannot include new .c/.o files since its a huge application and has been running for years. How can I get rid of this error?
Code extractes of makefile:
RPCAPPN = api
LINK = cc
$(RPCAPPN)_server: $(RPCAPIOBJ)
$(LINK) -g $(RPCAPIOBJ) -o $(RPCAPPN)_server $(IDALIBS) $(LIBS) $(ORALIBS) $(COMMONLIB) $(LIBAPI) $(CCLIB) $(THREADLIB) $(DBSERVERLIB) $(ENCLIB)
Try adding -nostartfiles to your linker options, i.e.
$(LINK) -nostartfiles -g ...
From the gcc documentation:
-nostartfiles
Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib or -nodefaultlibs is used.
This causes crt1.o not to be linked (it's normally linked by default) - normally only used when you implement your own _start code.
-shared link option must be used when you compile a .so
The issue for me was, I by mistake put int main() in a namespace. Make sure don't do that otherwise you will get this annoying link error.
Hope this helps anyone :)
I had similar result when trying to build a new test project with boost, and it turned out that I was missing one declaration :
#define BOOST_TEST_MODULE <yourtestName>
I had this same problem when creating my c project, and I forgot to save my main.c file, so there was no main function.
I had a similar result when compiling a Fortran program that had C++ components linked in. In my case, CMake failed to detect that Fortran should be used for the final linking. The messages returned by make then ended with
[100%] Linking CXX executable myprogram
/lib/../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
make[3]: *** [myprogram] Error 1
make[2]: *** [CMakeFiles/myprogram.dir/all] Error 2
make[1]: *** [CMakeFiles/myprogram.dir/rule] Error 2
make: *** [myprogram] Error 2
The solution was to add
set_target_properties(myprogram PROPERTIES LINKER_LANGUAGE Fortran)
to the CMakeLists.txt, so that make prints out:
[100%] Linking Fortran executable myprogram
[100%] Built target myprogram
I had the same issue with a large CMake project, after I moved some functions from one code file to another. I deleted the build folder, recreated it and rebuilt. Then it worked.
Generally, with suddenly appearing linker errors, try completely deleting your build folder and rebuilding first. That can save you the headaches from trying to hunt down an error that actually simply shouldn't be there: There might be CMake cache variables floating around that have the wrong values, or something was renamed and not deleted, ...
I had the same issue as to OP but on on FreeBSD 13.1.
What solved the issue was simply adding:
int main()
{
}
Since the .cpp file was only an object file containing definitions and declarations using:
extern "C"
{
<all definitions and declarations code goes here>
}
Every time I tried compiling this, the compiler kept throwing the same error as to OP.
So all I did was add an empty main() function all the way at the bottom and code compiled with no errors.

Resources