So I am looking to compile this project https://github.com/MMquant/bfx-cpp-api using the example code. I have included the cryptopp file that was suggested in the read me. It is found here: https://github.com/weidai11/cryptopp.
I am using Ubutnu version 17.10 and the GNU compiler.
Here's how I am compiling:
g++ example.cpp BitfinexAPI.cpp BitfinexAPI.hpp -Icryptopp -I. -o a -w -std=c++17
It seems strange that BitFinex would support broken code so I am fairly sure that the issue must be something that I am doing.
The errors I am getting are related to line 936 where the datatype 'byte' is not declared. My prediction is that I am missing a header file somewhere but any help would be appreciated.
$ g++ example.cpp BitfinexAPI.cpp BitfinexAPI.hpp -Icryptopp -I. -o a -w -std=c++17
BitfinexAPI.cpp: In static member function ‘static int BitfinexAPI::getBase64(const string&, std::__cxx11::string&)’:
BitfinexAPI.cpp:936:5: error: ‘byte’ was not declared in this scope
byte buffer[1024] = {};
^~~~
BitfinexAPI.cpp:936:5: note: suggested alternative:
In file included from ../cryptopp/seckey.h:9:0,
from ../cryptopp/hmac.h:9,
from BitfinexAPI.cpp:37:
../cryptopp/config.h:222:23: note: ‘CryptoPP::byte’
typedef unsigned char byte;
^~~~
BitfinexAPI.cpp:940:9: error: ‘buffer’ was not declared in this scope
buffer[i] = content[i];
^~~~~~
BitfinexAPI.cpp:940:9: note: suggested alternative: ‘setbuffer’
buffer[i] = content[i];
^~~~~~
setbuffer
BitfinexAPI.cpp:943:21: error: ‘buffer’ was not declared in this scope
StringSource ss(buffer, content.length(), true, new Base64Encoder( new StringSink(encoded), false));
^~~~~~
BitfinexAPI.cpp:943:21: note: suggested alternative: ‘setbuffer’
StringSource ss(buffer, content.length(), true, new Base64Encoder( new StringSink(encoded), false));
^~~~~~
setbuffer
BitfinexAPI.cpp: In static member function ‘static int BitfinexAPI::getHmacSha384(const string&, const string&, std::__cxx11::string&)’:
BitfinexAPI.cpp:963:33: error: ISO C++ forbids declaration of ‘type name’ with no type [-fpermissive]
SecByteBlock byteKey((const byte*)key.data(), key.size());
^~~~
BitfinexAPI.cpp:963:27: error: expected primary-expression before ‘const’
SecByteBlock byteKey((const byte*)key.data(), key.size());
^~~~~
BitfinexAPI.cpp:963:27: error: expected ‘)’ before ‘const’
Here's how I am compiling:
g++ example.cpp BitfinexAPI.cpp BitfinexAPI.hpp -Icryptopp -I. -o a -w -std=c++17
It seems strange that BitFinex would support broken code so I am fairly sure that the issue must be something that I am doing.
The errors I am getting are related to line 936 where the datatype 'byte' is not declared. My prediction is that I am missing a header file somewhere but any help would be appreciated.
@kabanus identified the problem.
Crypto++ used to provide a byte
in the global C++ namespace. It was there for two reasons. First, it was a convenience item on Linux. You could use byte
instead of CryptoPP::byte
. Second, it avoided compiler errors on Windows. Microsoft SDK's provide a byte
in the global namespace, and if we put a byte
at CryptoPP::byte
then compile errors resulted from ambiguous definitions.
C++17 came along and offered a std::byte
; see P0298R0, A byte type definition. The global Crypto++ byte
broke Linux when folks used a using namespace std
. And it completely broke Microsoft because Microsoft SDK's provides a global byte
. Ironically, the authors of P0298R0 work for Microsoft.
Crypto++ placing a byte
in the global namespace was a C++ No-No. We got away with it for years, but it jumped up and bit us in C++17. We moved it into our namespace where it belongs. The check-in occurred at Commit 00f9818b5d8e, which happened after 5.6.5 was released and prior to 6.0 release.
Looking at the source for BitfinexAPI.cpp
, this is probably the solution... open BitfinexAPI.cpp
, and add the following at the top of the file:
// CRYPTOPP_NO_GLOBAL_BYTE signals byte is at CryptoPP::byte
#if defined(CRYPTOPP_NO_GLOBAL_BYTE)
using CryptoPP::byte;
#endif
Also see std::byte on the Crypto++ wiki. We took the time to document it because of all the problems std::byte
, Microsoft's global byte
and our byte
definitions are going to cause.
Related, you don't need to specify the C++ header on the command line. The compile error is due to the changes detailed above. All you need is:
g++ -std=c++17 example.cpp BitfinexAPI.cpp -I. ./cryptopp/libcryptopp.a -o example.exe
This assumes a directory structure of:
- bfx-api/
|
+- cryptopp/
The cryptopp/libcryptopp.a
is a convenient way to sidestep those stupid Linux path problems that have existed for years. You link against the static archive which means you don't need a library at runtime.
Now open in the BFX issue tracker: Crypto++ byte change at Crypto++ 6.0. It should help the project engineer around the changes.