티스토리 뷰

cmake

[CMake,ENG/KOR] compile protobuf with CMake

4whomtbts 2019. 12. 24. 01:19

한글은 아래에 있습니다.

This post deals with "How to trigger protoc with your CMake". 

I struggled to trigger my protoc with my CMake, I refered to some projects's CMake files that are expected 

to use gRPC library in the project and one of those is gRPC project(It's no-brainer lol). I read Its CMakeLists.txt

The build script did its job normally per se, I excerpted some of core codes(which runs protocol buffer compiler(protoc)) 

and I appended the codes to my project's CMakeLists.txt. But It didn't work. I struggle to make it work about 6hours. 

There was nothing particular reason that I had to run protoc in CMake, since there were only 2 proto files in my project. But I wanted to achieve full automation of build process.

Manually triggering proto compiler and move byproduct to appropriate directory is not COOL. 

That was point. Thus, I started my journey to seize the full automation of build process. 

Anyway, I found solution myself. Instead of using "add_custom_command" which gRPC uses in their build script 

I made protoc to be trigger by "excute_process" , Let's get down to the brass tack, Lemme show you my code

If you are either new to CMake or not accustomed to CMake, It would be better to read my previous posts 

(They are written in korean, But I think you could refer original document which is cited in the post 

during read CMake examples and see results of them that I wrote.)

that deal with some kind of command and topic that appear in a below code.

https://4whomtbts.tistory.com/72

 

[cmake,KOR] LIST

참고 : CMake의 LIST는 배열과 같은 역할을 합니다. 읽기 list(LENGTH <출력변수>) : 출력변수에 매개변수로 넣은 list의 길이를 대입 list(GET <인덱스> [<인덱스> ...] <출력변수>) : 출력변수에..

4whomtbts.tistory.com

https://4whomtbts.tistory.com/73

 

[CMake, KOR] foreach - 1

참고 : https://cmake.org/cmake/help/latest/command/foreach.html CMake에도 여느 프로그래밍 언어처럼 반복문이 있습니다. 위와 같은 문법으로 씁니다. 여기서 items 는 list나 세미콜론, 공백문자를 포함한 s..

4whomtbts.tistory.com

It's my project structure and I want to generate and place compiled proto .cc,.h into proto-gen. Lemme me show you 

How I could do that.

file(GLOB _all_proto_files *.proto)
SET(_proto_gen_dir ${CMAKE_CURRENT_SOURCE_DIR}/proto-gen)

foreach(__proto_file ${_all_proto_files})
    get_filename_component(__current_proto ${__proto_file} NAME)
    execute_process(COMMAND protoc -I=${CMAKE_CURRENT_SOURCE_DIR}
            --cpp_out=${_proto_gen_dir}
            ${__current_proto}
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endforeach(__proto_file)

I haven't covered a file method at a first line of code. Brifely, the code saves absolute path+<filename>.proto 

into _all_proto_files(You could name of it whatever you want). below line is result of file(I printed it with CMake message,

which is omitted in above example code) 

 /home/jun/Desktop/workspace/cproj/propaganda/Bar.proto;/home/jun/Desktop/workspace/cproj/propaganda/Foo.proto;/home/jun/Desktop/workspace/cproj/propaganda/Student.proto

execute_process literally excutes process with passed COMMAND. Please read document If you are interested more information about It.

https://cmake.org/cmake/help/v3.12/command/execute_process.html

 

execute_process — CMake 3.12.4 Documentation

execute_process Execute one or more child processes. execute_process(COMMAND [args1...]] [COMMAND [args2...] [...]] [WORKING_DIRECTORY ] [TIMEOUT ] [RESULT_VARIABLE ] [RESULTS_VARIABLE ] [OUTPUT_VARIABLE ] [ERROR_VARIABLE ] [INPUT_FILE ] [OUTPUT_FILE ] [ER

cmake.org

RESULT

 

한글

 

이 포스트에서는, CMake 로 protoc 를 작동시키는 방법을 다룹니다. 

이걸 하기 위해서 꽤 오래 씨름했는데, gRPC 를 사용하는 프로젝트의 CMakeLists.txt를 참고하고자 마음을 먹었습니다.

그리고 그런 프로젝트 중 하나는 gRPC 프로젝트 그 자체였죠.. 그래서 gRPC의 CMakeLists를 참고했는데

그대로 쓰면 잘 돌아갔습니다.

필요한 코드만 뽑아내서 넣으면 안 됬습니다. 어차피 proto 파일은 2개밖에 없어서 굳이 안 해도 되지만, 빌드를 자동화하고 싶어서 열심히 찾아봤습니다. 왜냐하면 매번 protoc 돌리고 만들어진 파일을 적당한 폴더에 옮겨담는 작업은 좀 그래서..

어쨌든, gRPC CMake에서는 add_custom_command를 쓰더라구요, 이게 제일 세련된 방법인 것 같은데 도저히 안 되서

그냥 이것저것 찾아보다가, execute_process 메소드를 사용해서 어찌저찌 됬습니다.  CMake에 처음이거나 익숙하지 않다면

아래의 포스팅을 보고 오시면 이해하는데 좋을겁니다.

https://4whomtbts.tistory.com/72

 

https://4whomtbts.tistory.com/73

 

위의 사진이 이 실습에서 제가 사용한 프로젝트 구조입니다. 따라할려면 저렇게 만들고 시작하세요. 

(cmake_install.cmake, CMakeCache.txt propaganda, propaganda.cbp 제외)

file(GLOB _all_proto_files *.proto)
SET(_proto_gen_dir ${CMAKE_CURRENT_SOURCE_DIR}/proto-gen)

foreach(__proto_file ${_all_proto_files})
    get_filename_component(__current_proto ${__proto_file} NAME)
    execute_process(COMMAND protoc -I=${CMAKE_CURRENT_SOURCE_DIR}
            --cpp_out=${_proto_gen_dir}
            ${__current_proto}
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endforeach(__proto_file)

file 메소드는 아직 포스팅 한 적이 없는데, 간략히 말하자면 저 코드는 현재 폴더에서 모든 proto 확장자를 가진 파일을

_all_proto_files 에 list 형식으로 담아주는 역할을 합니다. 그래서 아래같은 결과가 나옵니다.

 /home/jun/Desktop/workspace/cproj/propaganda/Bar.proto;/home/jun/Desktop/workspace/cproj/propaganda/Foo.proto;/home/jun/Desktop/workspace/cproj/propaganda/Student.proto

execute_process는 말 그대로 프로세스를 실행시켜줍니다. variation이 많은 명령이라서 아래의 링크를 참고하세요.

https://cmake.org/cmake/help/v3.12/command/execute_process.html

 

execute_process — CMake 3.12.4 Documentation

execute_process Execute one or more child processes. execute_process(COMMAND [args1...]] [COMMAND [args2...] [...]] [WORKING_DIRECTORY ] [TIMEOUT ] [RESULT_VARIABLE ] [RESULTS_VARIABLE ] [OUTPUT_VARIABLE ] [ERROR_VARIABLE ] [INPUT_FILE ] [OUTPUT_FILE ] [ER

cmake.org

결과

'cmake' 카테고리의 다른 글

[CMake, ENG] Let's use "FUNCTION" in CMake  (0) 2019.12.27
[CMake, KOR/ENG] How to generate gRPC c++ code with CMake  (0) 2019.12.24
[CMake, KOR] get_filename_component  (0) 2019.12.23
[CMake, KOR] foreach - 1  (0) 2019.12.23
[CMake,KOR] LIST  (0) 2019.12.23
댓글