monero-cpp
monero-cpp copied to clipboard
Error when linking a static library
I'm having some trouble linking the monero-cpp library to my simple project. I created a simple test project to help you figure out what exactly is going wrong. We are talking about MSYS2 MinGW64 assembly on Windows 10 x64. And so what needs to be done:
git clone [email protected]:sdcwen/monero-test.git
cd ./monero-test/
git submodule update --init
cd ./external/monero-cpp/
git checkout v0.7.6
cd ../../
Then you need to replace monero-test/external/monero-cpp/CMakeLists.txt
with the monero-test/patch/CMakeLists.txt
file. This file contains some fixes that allow you to add monero-cpp
via add_subdirectory
to your project.
-set(MONERO_PROJECT "${CMAKE_SOURCE_DIR}/external/monero-project" CACHE STRING "Monero project source directory")
+set(MONERO_PROJECT "${CMAKE_CURRENT_LIST_DIR}/external/monero-project" CACHE STRING "Monero project source directory")
...
-include_directories(src/)
+include_directories(${CMAKE_CURRENT_LIST_DIR}/src/)
...
-set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/external-libs)
+set(EXTERNAL_LIBS_DIR ${CMAKE_CURRENT_LIST_DIR}/external-libs)
With the help of ${CMAKE_CURRENT_LIST_DIR}
I simply indicate that I want to build the rest of the paths relative to the current position of the file in the system. If this is not done, then add_subdirectory
will not work correctly.
I also change the building of the dynamic library to a static one. I think this should not break anything, because all other libraries are imported from monero-project
as static
and the monero-cpp
library itself can also be static
.
- add_library(monero-cpp SHARED ${LIBRARY_SRC_FILES})
+ add_library(monero-cpp STATIC ${LIBRARY_SRC_FILES})
Okay now we are ready to assemble. I use a customized QtCreator for building, which pulls the MSYS2 MinGW64 environment (which can be taken in monero-test/env/msys64/mingw64/paths.txt
). Or you can do it through the MSYS2 MinGW64 terminal:
mkdir .build
cd ./.build
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug ..
cmake --build . --target all
And now I'm getting an error that I can't do anything about and don't understand why it's happening at all:
[27/28] Linking CXX executable monero-test.exe
FAILED: monero-test.exe
cmd.exe /C "cd . && C:\msys64\mingw64\bin\c++.exe -g @CMakeFiles\monero-test.rsp -o monero-test.exe -Wl,--out-implib,libmonero-test.dll.a -Wl,--major-image-version,0,--minor-image-version,0 && cd ."
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/monero-test/external/monero-cpp/external/monero-project/build/release/src/device_tr
ezor/libdevice_trezor.a(protocol.cpp.obj):protocol.cpp:(.text+0x43cb): undefined reference to `hmac_keccak_hash'
collect2.exe: error: ld returned 1 exit status
[28/28] Linking CXX executable external\monero-cpp\scratchpad.exe
ninja: build stopped: subcommand failed.
In fact, I simply copied the contents of monero-test/external/monero-cpp/test/sample_code.cpp
into my main.cpp
file. And it is worth noting that sample_code.cpp
itself compiles without problems.
And also it is worth noting the problem with inclusions. In my main.cpp, I need to add the following includes at the very beginning:
#include <boost/asio.hpp>
#include <windows.h>
This is some kind of well-known problem. If this is not done, then we get a million errors. And what is again strange in sample_code.cpp
there is no such problem. This issue is pulled from #include "wallet/monero_wallet_full.h"
.
Interestingly, if in monero-test/external/monero-cpp/CMakeLists.txt
one or only one monero-cpp
static lib is linked to the sample_code
target, then sample_code
compilation will end with the same error: undefined reference to hmac_keccak_hash
.
In my opinion, this is very strange behavior. I can't explain it. In essence, the monero-cpp
and sample_code
targets contain the same set of static libraries in target_link_libraries
, with only one difference, an additional unbound
is linked to the monero-cpp
target, which can also be removed and nothing bad will happen. That is, if in target_link_libraries
for the monero-cpp
target, register all the static libraries that are in the target_link_libraries
for the sample_code
target, and link the monero-cpp
static library through target_link_libraries
to the sample_code
target, then this breaks compilation. If, instead, the entire list of static libraries is directly linked to the target sample_code
(as is done now), then this does not break anything.
Maybe I'm using your project in a wrong way? Maybe I'm somehow doing something wrong with CMake scripts?
I would also like to draw attention to the main CMakeLists.txt
. Why is just include_directories
used everywhere? It would be more convenient for developers to use target_include_directories
. If the include paths are connected to a certain target, then when I link this target to my target, I will inherit all the includes, all the paths to them. Otherwise, I have to propagate it myself in my CMakeLists.txt
:
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/src)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/contrib/epee/include)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/external)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/external/easylogging++)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/external/rapidjson/include)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/src)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/src/wallet)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/src/wallet/api)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/src/hardforks)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/monero-project/src/crypto/crypto_ops_builder/include)
target_include_directories(monero-cpp PUBLIC ${CMAKE_SOURCE_DIR}/external/monero-cpp/external/libsodium/include/sodium)
If this is not done, then with a simple use of the library, when I include #include "wallet/monero_wallet_full.h"
somewhere in the depths of the includes, there is an include that cannot find its way. For example this happened to monero-test/external/monero-cpp/external/libsodium/include/sodium/export.h
. It's just included somewhere as #include "export.h"
.
Have you confirmed that monero-cpp fully builds standalone? It only fails building from an external project?
Have you confirmed that monero-cpp fully builds standalone? It only fails building from an external project?
Yes, monero-cpp
builds completely without problems if you follow the build instructions. The problems start when I try to link it as a static library into my project. Basically I'm doing the same as in sample_code
, but it doesn't work.