Build your project structure before using cmake:
# tree .
.
├── CMakeLists.txt
├── go
│ ├── CMakeLists.txt
│ ├── go.mod
│ └── module.go
└── test.cpp
Files
./CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(test)
add_subdirectory(go)
set(TARGET test)
set(SRCS test.cpp)
add_executable(${TARGET} ${SRCS})
target_link_libraries(${TARGET} goshim pthread)
./test.cpp
#include <iostream>
#include <string>
#include "go/module.h"
int main() {
int res = Add(1, 2);
std::cout << res << std::endl;
GoString str;
str.p = "Hello World";
str.n = strlen(str.p);
Print(str);
std::string s = "Go-Module";
char *cstr = new char[s.length()+1];
std::strcpy (cstr, s.c_str());
cstr = StrFxn(cstr);
std::cout << cstr << std::endl;
delete[] cstr;
return 0;
}
./go/CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(test_go)
set(TARGET shim_go)
set(SRCS module.go)
set(LIB module.so)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${LIB}
DEPENDS ${SRCS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND env GOPATH=${GOPATH} go build -buildmode=c-archive
-o "${CMAKE_CURRENT_BINARY_DIR}/${LIB}"
${CMAKE_GO_FLAGS} ./...
COMMENT "Building Go library")
add_custom_target(${TARGET} DEPENDS ${LIB} ${HEADER})
add_library(goshim STATIC IMPORTED GLOBAL)
add_dependencies(goshim ${TARGET})
set_target_properties(goshim
PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${LIB}
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR})
./go/module.go
package main
import "C"
import (
"sort"
"fmt"
)
//export Add
func Add(a, b int) int {
return a + b
}
//export Sub
func Sub(a, b int) int {
return a - b
}
//export Print
func Print(str string) {
fmt.Printf("Go prints: %s\n", str)
}
func strFxn(input string) string {
return "Hello " + input + " World"
}
//export StrFxn
func StrFxn(cinput *C.char) *C.char {
// C data needs to be manually managed in memory.
// But we will do it from C++.
input := C.GoString(cinput)
return C.CString(strFxn(input))
}
//export Sort
func Sort(vals []int) {
sort.Ints(vals)
}
func main() {
// We need the main function to make possible
// CGO compiler to compile the package as C shared library
}
./go/go.mod
total 16
module demo/module
go 1.16
Run
# cmake .
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/demo
# make
[ 33%] Building Go library
[ 33%] Built target shim_go
[ 66%] Building CXX object CMakeFiles/test.dir/test.cpp.o
[100%] Linking CXX executable test
[100%] Built target test
# ./test
3
Go prints: Hello World
Hello Go-Module World