In C/C++, you need to actually declare functions before calling them. The Arduino preprocessor lets you cheat and put functions wherever by automatically pushing a pile of declarations to the top of the file - if your CMake doesn't do this, you'll have to add in declarations yourself.
For example:
Arduino:
void setup() {}
void loop() { foo(); }
void foo() {}
This works even though foo is undeclared before loop() because Arduino pushes a void foo(); on top of everything.
Standard C/C++:
void foo(); // <-- important
void setup() {}
void loop() {foo();}
void foo() {}
Declarations need to come first.
Including header files at the top is your job. #include exists for a reason, after all. CMake will not, unless you tell it to, automatically add #include lines into your code.