So I got bored of trying to understand how to make CMake work and wanted to move to something that I find prettier. That's why I'm trying to use Gradle in this C++ project.
I'm trying to use a C++ library GameEngine
of mine in a new C++ application project called GameEngineGame
. The GameEngine
library has been successfully built and published with Gradle into a local Maven repository available at a location defined by the CPPMavenRepo
environment variable (read with System.getenv('CPPMavenRepo')
).
When I try to run gradle build
in the GameEngineGame
project, the dependency is found, but during the linking phase, I somehow get an error message telling me that I have unresolved external symbols.
$ gradle build
> Task :linkTest FAILED
Main.obj : error LNK2019: unresolved external symbol "public: static class Engine::Engine & __cdecl Engine::Engine::get(void)" (?get@Engine@1@SAAEAV11@XZ) referenced in function main
G:\<redacted>\GameEngineGame\build\exe\test\GameEngineGameTest.exe : fatal error LNK1120: 1 unresolved externals
> Task :linkDebug FAILED
Main.obj : error LNK2019: unresolved external symbol "public: static class Engine::Engine & __cdecl Engine::Engine::get(void)" (?get@Engine@1@SAAEAV11@XZ) referenced in function main
G:\<redacted>\GameEngineGame\build\exe\main\debug\GameEngineGame.exe : fatal error LNK1120: 1 unresolved externals
FAILURE: Build completed with 2 failures.
1: Task failed with an exception.
[...]
The code in the Main.cpp
file is short. I only call a static function Engine::Engine::get()
and declare a struct Component::Position p
. This latter does not create any error, but the first line does, because of the missing shared object from the library.
#include <iostream>
#include <Engine/Engine.hpp>
#include <Component/Position.hpp>
int main(int, char**) {
Engine::Engine& e = Engine::Engine::get();
Component::Position p;
std::cout << "Hello, world!\n";
}
So, all headers are found (I made sure of it), but the "linker failed while linking", so I don't have any binary associated with the functions. I'm deducing that the dll/lib file has not been given to the linker, but I can't find if it's the case, and in that case how to fix it. I suppose I'm missing something in the build.gradle
, but can't find what. There is very little help online, a pity.
You can find bellow the build.gradle
file for the GameEngineGame
C++ app project.
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample C++ project to get you started.
* For more details take a look at the Building C++ applications and libraries chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.6.1/userguide/building_cpp_projects.html
*/
plugins {
// Apply the cpp-application plugin to add support for building C++ executables
id 'cpp-application'
// Apply the cpp-unit-test plugin to add support for building and running C++ test executables
id 'cpp-unit-test'
}
repositories {
maven {
url = System.getenv('CPPMavenRepo')
}
}
// Set the target operating system and architecture for this application
application {
targetMachines.add(machines.windows.x86_64)
dependencies {
implementation 'com.sample:GameEngine:0.0.1'
}
}
By the way, as you can see in the comment, I used gradle init
in this project with the prepared configuration for C++ apps. For the library, I also used it, but with the configuration for C++ libs.