0

I need some help with adding files to the code base by adding them to the autotools build system. Other posts that try to answer the same question haven't helped me. I am experimenting with Bitcoin's codebase and I am trying to add new files to the codebase. I am trying to add a static library in the src/Makefile.am by adding these lines:

LIBGLYPH=libglyph.a

libglyph_a_SOURCES = \
glyph/glp.c \
  glyph/glp_utils.c \
  glyph/glp_rand.c \
  glyph/glp_rand_openssl_aes.c \
  glyph/FFT/FFT_1024_65537.c \
  glyph/converter.c
libglyph_a_CPPFLAGS = $(AM_CPPFLAGS)
libglyph_a_CFLAGS =
libglyph_a_CXXFLAGS = $(AM_CXXFLAGS)

    EXTRA_LIBRARIES += \
  $(LIBBITCOIN_CRYPTO) \
  $(LIBBITCOIN_UTIL) \
  $(LIBBITCOIN_COMMON) \
  $(LIBGLYPH) \
  $(LIBBITCOIN_CONSENSUS) \
  $(LIBBITCOIN_SERVER) \
  $(LIBBITCOIN_CLI) \
  $(LIBBITCOIN_WALLET) \
  $(LIBBITCOIN_ZMQ)

bitcoin_tx_LDADD = \
  $(LIBUNIVALUE) \
  $(LIBBITCOIN_COMMON) \
  $(LIBBITCOIN_UTIL) \
  $(LIBBITCOIN_CONSENSUS) \
  $(LIBBITCOIN_CRYPTO) \
  $(LIBGLYPH) \
  $(LIBSECP256K1)

bitcoind_LDADD = \
  $(LIBBITCOIN_SERVER) \
  $(LIBBITCOIN_COMMON) \
  $(LIBUNIVALUE) \
  $(LIBBITCOIN_UTIL) \
  $(LIBBITCOIN_WALLET) \
  $(LIBBITCOIN_ZMQ) \
  $(LIBBITCOIN_CONSENSUS) \
  $(LIBBITCOIN_CRYPTO) \
  $(LIBLEVELDB) \
  $(LIBLEVELDB_SSE42) \
  $(LIBMEMENV) \
  $(LIBGLYPH) \
  $(LIBSECP256K1)

I have tried at least 30 different compilation attempts where I reordered the compilation and/or renamed the library.

Error:

make[3]: Entering directory '/home/joe/glyph/glyphCodebase/BitcoinUnlimited/src/secp256k1'
make[3]: Leaving directory '/home/joe/glyph/glyphCodebase/BitcoinUnlimited/src/secp256k1'
  CXXLD    bitcoind
libbitcoin_common.a(libbitcoin_common_a-key.o): In function `CKey::MakeNewKey()':
/home/joe/glyph/glyphCodebase/BitcoinUnlimited/src/key.cpp:25: undefined reference to `glp_gen_sk(glp_signing_key_st*)'
libbitcoin_common.a(libbitcoin_common_a-key.o): In function `CKey::GetPubKey() const':
/home/joe/glyph/glyphCodebase/BitcoinUnlimited/src/key.cpp:48: undefined reference to `glp_gen_pk(glp_public_key_st*, glp_signing_key_st)'
collect2: error: ld returned 1 exit status
Makefile:3556: recipe for target 'bitcoind' failed
make[2]: *** [bitcoind] Error 1
make[2]: Leaving directory '/home/joe/glyph/glyphCodebase/BitcoinUnlimited/src'
Makefile:9207: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/joe/glyph/glyphCodebase/BitcoinUnlimited/src'
Makefile:670: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1

This error occurs despite libglyph.a being made and containing the functions. I have tried to add the library header and C files to common library with no luck either. I have rearranged the EXTRA_LIBRARIES section of the Makefile.am with no luck.


In order to simplify the problem, here is a really simple example that spits out the same error:

Adding 1 .h and 1 .cpp file to 1 already made library: libbitcoin_common new files: src/testFile.cpp src/testFile.h

testFile.h:

void testFunction();

testFile.cpp

#include "testFile.h"
#include <stdio.h>

void testFunction() {
    printf("I am a test function");
}

added following lines to key.cpp:

#include "testFile.h"

void CKey::MakeNewKey()
{
    testFunction();
     ...
     ...
     ...
}

Then in src/Makefile.am

BITCOIN_CORE_H = \
testFile.h \
...
...

and the testFile to the common library, where key.cpp is, as mentioned by Pieter Wuille here

# common: shared between bitcoind, and bitcoin-qt and non-server tools
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_common_a_SOURCES = \
  amount.cpp \
  base58.cpp \
  chainparams.cpp \
  coins.cpp \
  compressor.cpp \
  core_read.cpp \
  core_write.cpp \
  keystore.cpp \
  netaddress.cpp \
  netbase.cpp \
  protocol.cpp \
  scheduler.cpp \
  script/sign.cpp \
  script/standard.cpp \
  key.cpp \
  testFile.cpp \
  $(BITCOIN_CORE_H)

The error:

libbitcoin_common.a(libbitcoin_common_a-key.o): In function 
`CKey::MakeNewKey()':
/home/joe/glyph/glyphCodebase/BitcoinUnlimited/src/key.cpp:23: undefined reference to `testFunction()

Please help me out with this. Thanks a lot

2 Answers 2

2

Adding a single source file and header is easier to do than adding a new library.

For a single source file, the file must come before any file that depends on it. So in your example, you should have

...
testFile.cpp \
key.cpp \
...

But you are really trying to add a new library. To do that, you need to add it to bitcoind_LDADD which is further down in Makefile.am. That way the linker knows to link it. For the linker, the dependencies need to be placed after the things that depend on it. So you can just adding $(LIBGLYPH) to the end of that list should work.

8
  • Wow thanks for such a quick response! I tried rearranging it and got the same error: libbitcoin_common.a(libbitcoin_common_a-key.o): In function CKey::MakeNewKey()': /home/joe/glyph/glyphCodebase/BitcoinUnlimited/src/key.cpp:23: undefined reference to testFunction()'
    – Joe N
    Commented Jan 7, 2018 at 18:27
  • I also added LIBGLYPH to bitcoind_LDADD and I tested adding it to the top and bottom and that also didn't worked
    – Joe N
    Commented Jan 7, 2018 at 18:37
  • You might need to add it to bitcoin_tx_LDADD too. Can you update your question with the full output of the make command?
    – Ava Chow
    Commented Jan 7, 2018 at 18:45
  • Also, did you remember to rerun autogen.sh and configure after modifying the makefile?
    – Ava Chow
    Commented Jan 7, 2018 at 18:48
  • I updated the post with all of the changes I made. I left them out at first because I thought it would be too much info. It doesn't work with the addition to bitcoin_tx_LDADD. I also tried the sources and cxx section all with libbitcoin_glyph as the name and glyph_libbitcoin_glyph_a instead libglyph_a and that didn't work. I use ./autogen.sh and ./configure everytime I make a change. Here is the file if you want to see it: drive.google.com/file/d/1eB_EnxfSG1erRgDpDNgU_q-PzPQYs0hp/…
    – Joe N
    Commented Jan 7, 2018 at 20:47
2

There were 2 problems with the code:

  1. you cannot compile c code with a c++ compiler without extern "C" in the header files of the C code. https://stackoverflow.com/questions/12066279/using-c-libraries-for-c-programs
  2. -fPIC might have to be used when compiling the C code (add it to the flags). I used liblibraryName_a_CFLAGS = -fPIC and liblibraryName_a_CXXFLAGS = -fPIC

For anyone that wants to see my makefile.am, go here: https://drive.google.com/file/d/1eB_EnxfSG1erRgDpDNgU_q-PzPQYs0hp/view?usp=sharing

Build systems are notoriously frustrating. If you have questions, leave a comment or ask me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.