0

I have a C application using CMake to generate Makefiles on Linux. The application contains .c as well as .proto files. Now I need to genearte .pb-c.c and .pb-c.h using protoc command in the CMakeLists.txt so that when I do cmake . the cmake generates the corresponding .pb-c and .pb-h. The protoc is used as:

execute_process(COMMAND bash -c "${PROTOC_PATH} --c_out=${CMAKE_CURRENT_SOURCE_DIR}/ --proto_path=${PROTO_DIR}/ ${PROTO_DIR}/*.proto")

The problem is that my protoc binary and related .so file is not in /usr/bin and /usr/lib or /usr/local/bin and /usr/local/lib. They are in a directory inside the project - $HOME/project-name/dependencies/bin/protoc and $HOME/project-name/dependencies/lib/libprotobuf.so.12

Due to this I am getting error - error while loading shared libraries: libprotobuf.so.12: cannot open shared object file: No such file or directory

But if I give the command as

execute_process(COMMAND bash -c "protoc--c_out=${CMAKE_CURRENT_SOURCE_DIR}/ --proto_path=${PROTO_DIR}/ ${PROTO_DIR}/*.proto") and run cmake . then it works fine as linker is able to get the .so file from /usr/lib

Mentioned below is a part of my CMakeLists.txt file

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath=${PROTOC_LIB_PATH} -L${PROTOC_LIB_PATH} -lprotobuf")

set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-rpath=${PROTOC_LIB_PATH} -L${PROTOC_LIB_PATH} -lprotobuf")

execute_process(COMMAND bash -c "${PROTOC_PATH} --c_out=${CMAKE_CURRENT_SOURCE_DIR}/ --proto_path=${PROTO_DIR}/ ${PROTO_DIR}/*.proto")

But it's not working due to aforementioned error.

Also for those who might say it's a duplicate I have looked into and tried the following SO questions:

Turning on linker flags with CMake

I don't understand -Wl,-rpath -Wl,

CMake link to external library

Does cmake have something like target_link_options?

CMAKE RPATH not working - could not find shared object file

https://serverfault.com/q/279068/435497

How to add linker flag for libraries with CMake?

https://serverfault.com/a/926072/435497

Yug Singh
  • 2,571
  • 3
  • 17
  • 42
  • Just `protobuf_generate_cpp(...)` like [here](https://github.com/Kitware/CMake/blob/master/Modules/FindProtobuf.cmake#L77). – KamilCuk Jan 01 '20 at 11:51
  • @KamilCuk `protobuf_generate_cpp(...)` generate **c++** files but I require *c* and there seems to be no way to generate them without using **protoc**. – Yug Singh Jan 01 '20 at 15:51
  • True. You have the [sources](https://github.com/Kitware/CMake/blob/master/Modules/FindProtobuf.cmake#L227), you can try to modify them. Btw. instead of `bash -c 'protoc arg'` just do `protoc arg`, no need for bash. – KamilCuk Jan 01 '20 at 16:32
  • @KamilCuk I have tried without `bash-c` but for some reason cmake is not executing the command without any error and thus not generating the required `.c` file from `.proto`. – Yug Singh Jan 01 '20 at 18:31

2 Answers2

2

If you do not have a special use case, you do not need to call protoc yourself. Let CMake do this for you.

Have a look at: https://cmake.org/cmake/help/v3.16/module/FindProtobuf.html and Cmake : find protobuf package in custom directory

zer0
  • 411
  • 4
  • 9
  • Thanks for the answer. `you do not need to call protoc yourself. Let CMake do this for you.` was what led me to do a bit more searching and ultimately I came across `find_program` which is what I was looking for and have posted as answer related to same. – Yug Singh Jan 01 '20 at 19:01
0

I found this link which has a script showing how to create a PROTOBUF_GENERATE_C function which can then be used to generate the .pb-c abd .pb-h files.

From the above script I got the idea to make use of find_program which is similar to find_library in a way that it lets you pass the PATHS/PATH option so that CMake looks for the required program in the mentioned path.

Yug Singh
  • 2,571
  • 3
  • 17
  • 42