Why I'm getting different merkleroot? I'm using merkle.cpp code (which uses the libbitcoin library for some helper functions) from Mastering Bitcoin book. 

I was trying to re-create Merkleroot hash for Bitcoin block #100000 containing 4 transactions:

 "tx": [
    "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",
    "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",
    "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4",
    "e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"
  ].


Thus, I modified main() function by adding hashes of all four txs:

int main()
{
    // Replace these hashes with ones from a block to reproduce the same merkle root.
    bc::hash_list tx_hashes{{
        bc::hash_literal("8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87"),
        bc::hash_literal("fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4"),
        bc::hash_literal("6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4"),
        bc::hash_literal("e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"),

    }};
    const bc::hash_digest merkle_root = create_merkle(tx_hashes);
    std::cout &lt;&lt; "Result: " &lt;&lt; bc::encode_base16(merkle_root) &lt;&lt; std::endl;
    return 0;
}


Compiling and running it gave me:

Current merkle hash list:
  15b88c5107195bf09eb9da89b83d95b3d070079a3c5c5d3d17d0dcd873fbdacc
  49aef42d78e3e9999c9e6ec9e1dddd6cb880bf3b076a03be1318ca789089308e

Current merkle hash list:
  6657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f3

Result: 6657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f3


while the actual merkleroot is different:

"merkleroot": "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",


What I did wrong?
You actually did get the same hash. It's just that every Bitcoin software displays hashes byte swapped. If you look closely, you'll see that the first byte of your result (66) matches the last byte of the displayed merkleroot. The second byte matches the second to last byte, and so on.

Internally, the merkleroot (and other hashes) are in the same order as the output of the hash function. But for display to users, they are always byte swapped.