DirectSound using MinGW: undefined reference 'DirectSoundCreate8' - c++

I want to use the DirectSound API (from DirectX) to process the audio Windows outputs. To do so, I created "libdsound.a" as described in the following paragraphs, because it seems like I cannot use .dll s or .lib s for the MinGW g++ compiler.
I installed the DirectX SDK and copied the dsound.lib to a folder called "directsound". From the mingw-w64 repository, I downloaded dsound.h and dsound.def to the directory "directsound" as well (all files I used were for x86).
Following this guide I used the dlltool command line to create the libdsound.a:
dlltool -d dsound.def -l libdsound.a
In CLion, I set up CMake in CMakeLists.txt the following way:
cmake_minimum_required(VERSION 3.9)
project(fourier)
set(CMAKE_CXX_STANDARD 11)
link_directories(PATHTOTHISDIR/directsound)
include_directories(PATHTOTHISDIR/directsound)
add_executable(fourier main.cpp)
target_link_libraries(fourier dsound)
CLion says the CMakeLists.txt file is fine. Every time I try to compile the program, building and linking seems to work fine, but then I get the following error message:
[ 50%] Building CXX object CMakeFiles/fourier.dir/main.cpp.obj
[100%] Linking CXX executable fourier.exe
CMakeFiles\fourier.dir/objects.a(main.cpp.obj): In function `main':
PATHTOPROJECT/main.cpp:11: undefined reference to `DirectSoundCreate8'
collect2.exe: error: ld returned 1 exit status
...
This is how main.cpp (the only source file) looks like:
#pragma comment(lib, "libdsound.a")
#include <windows.h>
#include <dsound.h>
int main() {
LPDIRECTSOUND8 directsound;
DirectSoundCreate8(NULL, &directsound, NULL);
WAVEFORMATEX waveformat;
// ....
EDIT Was able to resolve it thanks to the advice of VTT. The way I created the libdsound.a was wrong. It should've been done like this:
dlltool -D dsound.dll -d dsound.def -l libsound.a -k
I should have also created the .def file on my own.
reimp -c -d dsound.lib
The dsound.dll should be placed in the same directory as the executable.

Related

Link GDAL library using CMake instead of g++

I wrote a program that reads a GeoTiff file with GDAL. To compile it, I write:
g++ my_program.cpp -lgdal
However, I want to run this code with Clion. How do I add this -lgdal to the CMake file?
The -l is an indication to the linker to link the gdal library to your executable, so the corresponding CMake command is target_link_libraries(). So your CMake might look something like this:
add_executable(MyExecutable my_program.cpp)
target_link_libraries(MyExecutable PRIVATE gdal)

Linking Paho C Mqtt library error in C++ Project

I'm trying to include the MQTT-C-Client-Library in a simple C++ project.
I have included the header file succesfully like this #include "MQTTClient.h". Compiling it in the linux terminal was printing this errors:
[xy#localhost mosquittoProject]$ sudo g++ *.cpp -o MQTTTest
/tmp/ccHn3s6m.o: In function `main':
mosquitto_test.cpp:(.text+0x11e): undefined reference to `MQTTClient_create'
mosquitto_test.cpp:(.text+0x13f): undefined reference to `MQTTClient_connect'
collect2: error: ld returned 1 exit status
I figured out that I need to link the library after some googling: Example MQTT Client Code not working C
Based on this question and answer I tried compiling it again like this:
sudo g++ -L/home/xy/Desktop/paho.mqtt.c/build/output/ *.cpp -l paho-mqtt3c -o MQTTTest
Which compiles fine but when running I get still an error.
Console commands and output:
[xy#localhost mosquittoProject]$ sudo g++ -L/home/xy/Desktop/paho.mqtt.c/build/output/ *.cpp -l paho-mqtt3c -o MQTTTest
[xy#localhost mosquittoProject]$ ./MQTTTest
./MQTTTest: error while loading shared libraries: libpaho-mqtt3c.so.1: cannot open shared object file: No such file or directory
I replaced the actual username by xy in this post.
What am I doing wrong here?
The problem looks like the library (libpaho-mqtt3c.so.1) is not on the library path.
It looks like you are linking against the build location of the library and have not installed it to the default system location (e.g. /usr/local/lib) by running sudo make install.
By default on Linux the runtime linker searches the locations listed in /etc/ld.so.conf and /etc/ld.so.conf.d. if you edit these remember to run sudo ldconfig to update the cache.
You can add the location of the library to the LD_LIBRARY_PATH environment variable e.g.:
$ LD_LIBRARY_PATH=/home/xy/Desktop/paho.mqtt.c/build/output/ ./MQTTTest

Eclipse: Edit toolchain (remove build step to create a shared library for CUDA)

I am trying to configure Eclipse such that it compiles a shared library in one project and uses it in another.
The problem is, that using the CUDA plugin for Eclipse one can only choose an executable generating project type.
So what I want to do is creating such a project and modify that toolchain such that Eclipse does not execute anything else than nvcc.
As you can see compiling the library is not a problem:
18:27:25 **** Incremental Build of configuration Default for project cudamath ****
make all
Building file: ../test.cu
Invoking: CUDA NVCC Compiler
nvcc --shared -Xcompiler -fPIC -o "cu_test.o" "../test.cu" && \
echo -n 'cu_test.d' ./ > 'cu_test.d' && \
nvcc -M "../test.cu" >> 'cu_test.d'
nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
Finished building: ../test.cu
The problem is that Eclipse then calls g++ which is that step of the toolchain I want to cut off:
Building target: cudamath
Invoking: C++ Linker
g++ -L/opt/cuda/lib64 -o "cudamath" ./cu_test.o -lcuda -lcublas -lcudart
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:32: recipe for target 'cudamath' failed
make: *** [cudamath] Error 1
Is there a way I can do this? I've been crawling through my project settings but I can't seem to find what I'm looking for.
Here's what I did using Nsight Eclipse Edition:
File... new CUDA C/C++ project
In the next dialog, select Shared Library...Empty Project, and give the project a name (let's say it is testlib)
Finish that wizard/dialog. A new testlib project is created in the project explorer on the left
In the project explorer on the left, right click on the project name and create a new folder for your source files
Open that folder and create your new source file. For this, I selected a CUDA C/C++ source file using the CUDA bitreverse "template". This creates a new source file with the bitreverse code in it.
change int main() { in your source file to int myfunc(){
save the source file and build the project. A new libtestlib.so is successfully built.

strange mingw linker errors with boost?

I've been working on this for a while now, and can't seem to make sense of the situation - partly bceause I don't fully understand what's going on (which is why I came here).
I'm doing a sort of boost hello world as follows:
#include <boost/thread/thread.hpp>
#include <cstdio>
void helloworld() {
std::printf("HELLO FROM A BOOST THREAD!");
}
int main(int argc, char **argv) {
boost::thread t(&helloworld);
t.join();
}
This is on Windows. I stored the Boost directory in C:\Boost. I ran bootstrap and bjam, and now have a stage/lib folder that contains all the .lib files. The lib files relating to the boost/thread library are:
libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib
Now I compile:
g++ -c main.cpp -I/Boost
that line works fine, I get main.o. Then:
g++ -o test.exe main.o -L/Boost/stage/lib -llibboost_thread-vc100-mt
And that's where the trouble happens. First of all, If I didn't type the -l argument the way I did, MinGW couldn't even find the file. Meaning, if I tried:
-lboost_thread-vc100-mt
instead of the way I typed it above (and how I thought it should be done), ld would exit with no such file. Anyway, this is now the output I'm getting from that line:
main.o:main.cpp:(.text+0x47): undefined reference to `_imp___ZN5boost6thread4joinEv'
main.o:main.cpp:(.text+0x55): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text+0x70): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text$_ZN5boost6threadC1IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE[boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type)]+0x23): undefined reference to `_imp___ZN5boost6thread12start_threadEv'
collect2: ld returned 1 exit status
Now somewhere in there, I can tell that these are apparently the functions I'm supposed to be getting from boost/thread, and apparently it does find the lib file, so why isn't it linking correctly?
Thank you very much for any help!
EDIT:
I've rebuilt boost using the bjam "stage" option
bjam toolset=gcc stage
Now, after the build completes, I'm left with a stage/lib folder with .a files, as is to be expected. These are the boost/thread related libraries:
libboost_thread-mgw45-mt-1_46_1.a
libboost_thread-mgw45-mt-d-1_46_1.a
However, linking as follows:
g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1
outputs the exact same errors. Also tried:
g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1 -static
I'm at a loss, still.
Solved the problem. Boost's headers are configured to be dynamically linked, but the dynamic libraries (dll's) are not built unless you specify:
--build-type=complete
when invoking bjam. After that, copy the appropriate dll to your application directory, but still use the
-L/BOOST_DIR/stage/lib -lname
when linking.
This set of library files:
libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib
are for the Visual Studio 2010 compiler. They won't work with GCC. If you want to use gcc/MinGW, you'll need to download/build a set of boost libraries for that compiler. Alternatively you can install VS 2010 and use that compiler (the free VC++ 2010 Express version should work fine if cost is an issue).
You can get a MinGW distribution with Boost already in the package from http://nuwen.net/mingw.html (32-bit target only, I believe).
To answer about getting the errors with using the MinGW libs:
The _imp_ prefixes on the symbols is an indication that g++ is looking to link to a a dll/shared library. The .lib file you have are for static libraries (which is what also what I get when doing a straightforward bjam build of the libraries). If you look in boost/thread/detail/config.hpp you'll see that for Win32 builds it defaults to building against a DLL library unless the MSVC or Intel compiler is being used.
I'm not even sure exactly how to build the DLL libraries - I'll have to look it up. In the meantime, you can use the following command to build your example such that it'll link against the static library. The BOOST_THREAD_USE_LIB macro build the .cpp file such that it'll expect to link against the static library:
g++ -I/Boost -DBOOST_THREAD_USE_LIB -c main.cpp

Compiling native C++ module for Node.js, linking to openSSL/libcrypto fails

I'm using Cygwin/Windows and I'm trying to build a native module for node.js. I intend to make use of the OpenSSL Library. I have installed openssl from the Cygwin package manager.
I have the following lines in my .cc file:
#include <openssl/dh.h>
and
DH* public_dh_key = DH_new();
But when I try to link/compile it with node-waf configure build, I get:
undefined reference to _DH_new
Edit:
Part of the build script:
def build(bld):
ppp= bld.new_task_gen('cxx', 'shlib', 'node_addon')
ppp.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall", "-L/usr/lib", "-lssl"]
...
(I have tried adding -lcrypto but still get the same result. I have also tried various combinations of "-lssl32","-lssleay32","-llibeay32".)
Edit
Output of the build script:
$ node-waf configure build
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for g++ : ok
Checking for node path : not found
Checking for node prefix : ok /usr/local
'configure' finished successfully (0.330s)
Waf: Entering directory `/usr/src/build'
[1/2] cxx: ppp.cc -> build/default/ppp_1.o
[2/2] cxx_link: build/default/ppp_1.o -> build/default/ppp.node build/default/libppp.dll.a
Creating library file: default/libppp.dll.a
default/ppp_1.o:/usr/src/build/../ppp.cc:289: undefined reference to `_HMAC'
collect2: ld returned 1 exit status
Waf: Leaving directory `/usr/src/build'
Build failed: -> task failed (err #1):
{task: cxx_link ppp_1.o -> ppp.node,libppp.dll.a}
Edit
I have the header file dh.h in usr/include/openssl
And I have the required files (libssl32.dll, libeay32.dll and ssleay32.dll) in /usr/lib/
The answer
jHackTheRipper answered this and got the credit for it, but the final answer is buried in the comments beneath his answer. So to summarise, the waf mantra is
obj.lib='crypto'
Adding -lcrypto should do the trick.
According to the nm output on my system _DH_new and _HMAC seem to be in the libcrypto (part of OpenSSL) dynamic library :
jhacktheripper#macbook-prolocal:~$ nm /usr/lib/libcrypto.dylib | grep _DH_new
0000000000036360 T _DH_new
0000000000036120 T _DH_new_method
jhacktheripper#macbook-prolocal:~$ nm /usr/lib/libcrypto.dylib | grep HMAC
0000000000090d40 T _HMAC
0000000000090c80 T _HMAC_CTX_cleanup
0000000000090910 T _HMAC_CTX_init
00000000000908c0 T _HMAC_CTX_set_flags
0000000000090940 T _HMAC_Final
0000000000090cc0 T _HMAC_Init
0000000000090a10 T _HMAC_Init_ex
0000000000090a00 T _HMAC_Update