Using rabbitmq-c as static library gives error: fatal error: amqp.h: No such file or directory

3.1k Views Asked by At

I am trying to build rabbitmq-c as a static library so I can use in AWS lambda.

I am able to build the examples following the documentation and those are working fine.

But now I am trying to use in my own project. Below are the steps I took:

  1. Cloned https://github.com/alanxz/rabbitmq-c inside third-party directory.
  2. Inside my source directory, I am building using cmake.

Below is my CMakeLists.txt

cmake_minimum_required(VERSION 3.1)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_BUILD_TYPE "Release")
project(executable LANGUAGES CXX)

SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
SET(BUILD_SHARED_LIBS OFF)

set(RABBITMQ_TARGET "<absolute_path_to_third_party_dir>/third_party/rabbitmq-c/")
add_definitions(-DAMQP_STATIC)
add_subdirectory(${RABBITMQ_TARGET})

include_directories(${LIBRABBITMQ_INCLUDE_DIRS})

add_executable(${PROJECT_NAME} execute_code.cpp)
target_link_libraries(executable PRIVATE ${RMQ_LIBRARY_TARGET})


  1. I run cmake .. -DBUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF (which works without any issue).
  2. But when I am executing make, it gives following error:
fatal error: amqp.h: No such file or directory
compilation terminated.
CMakeFiles/executable.dir/build.make:62: recipe for target 'CMakeFiles/executable.dir/execute_code.cpp.o' failed
make[2]: *** [CMakeFiles/executable.dir/execute_code.cpp.o] Error 1
CMakeFiles/Makefile2:169: recipe for target 'CMakeFiles/executable.dir/all' failed
make[1]: *** [CMakeFiles/executable.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

Here is my execute_code.cpp (I am removing unnecessary code just for here)

#include<iostream>
#include <amqp.h>
#include <amqp_tcp_socket.h>

using namespace std;

int main(int argc, char** argv) {
  char const *hostname;
  int port, status;
  char const *exchange;
  char const *bindingkey;
  amqp_socket_t *socket = NULL;
  amqp_connection_state_t conn;

  amqp_bytes_t queuename;

  conn = amqp_new_connection();
  socket = amqp_tcp_socket_new(conn);
  return 0;
}

when I am not using

#include <amqp.h>
#include <amqp_tcp_socket.h>

I am able to build rabbitmq-static, below is the make response

Scanning dependencies of target rabbitmq-static
[ 35%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_framing.c.o
[ 37%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_api.c.o
[ 40%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_connection.c.o
[ 42%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_mem.c.o
[ 44%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_socket.c.o
[ 46%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_table.c.o
[ 48%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_url.c.o
[ 51%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_tcp_socket.c.o
[ 53%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_time.c.o
[ 55%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_consumer.c.o
[ 57%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_openssl.c.o
[ 60%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_openssl_hostname_validation.c.o
[ 62%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_hostcheck.c.o
[ 64%] Building C object third_party/rabbitmq-c/librabbitmq/CMakeFiles/rabbitmq-static.dir/amqp_openssl_bio.c.o
[ 66%] Linking C static library librabbitmq.a
[ 66%] Built target rabbitmq-static

It is able to generate librabbitmq.a, so it is able to build statically.

I tried with https://github.com/alanxz/rabbitmq-c/releases/tag/v0.10.0 which is the latest stable version. But still the same error.

I tried searching regarding the issue, but couldn't find anything helpful.

I am pretty much newbie to cmake, Can you please tell me what I am doing wrong or am I missing something?

2

There are 2 best solutions below

2
On BEST ANSWER

The rabbitmq-c repository sets the LIBRABBITMQ_INCLUDE_DIRS variable in the rabbitmq-c/librabbitmq sub-directory, then also sets it using PARENT_SCOPE so it is also available in the top-level rabbitmq-c directory. See that code here:

set(LIBRABBITMQ_INCLUDE_DIRS
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${SOCKET_IMPL}
    ${MSINTTYPES_INCLUDE}
    )

include_directories(${LIBRABBITMQ_INCLUDE_DIRS})

set(LIBRABBITMQ_INCLUDE_DIRS
    ${LIBRABBITMQ_INCLUDE_DIRS}
    PARENT_SCOPE)

However, when you include the rabbitmq-c repo in your project via add_subdirectory, it introduces an additional scope, and the LIBRABBITMQ_INCLUDE_DIRS variable is not available in this parent-parent scope. You will have to either:

  1. Re-organize your CMake project such that your project sits within the rabbitmq-c repository (although this is not scalable, and probably not what you want to do).
  2. Modify the top-level rabbitmq-c CMake file to further extend the scope of this variable.
  3. Install rabbitmq-c on your machine, and use a CMake Find Module or a CMake configuration file (e.g. rabbitmq-c-config.cmake) furnished by rabbitmq-c to locate the installed software.
0
On

A bit late to the party, I stumbled onto the same issue today.

None of the 3 solutions proposed by Kevin would suit my needs (the lib is declared as a submodule so I can't modify it, won't install on the production machines)

The solution for me was to add rabbitmq include directories to the target that links the lib :

target_include_directories("${PROJECT_NAME}" PUBLIC include/ path/to/rabbitmq-c/librabbitmq)