I work on C++ project, i use CMake to build my file. My build fail cause
undefined reference to `Software::Software()'
, but I do not see the problem. If you have an idea, do not hesitate, thank you
Files architecture:
CMake :
# cmake_minimum_required(VERSION <specify CMake version here>)
project(untitled)
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_CXX_STANDARD 11)
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_executable(untitled ${SOURCES})
Software.h :
#include <string>
class Software{
private :
std::string name;
public :
Software();
}
Software.cpp :
#include "Software.h"
Software::Software() {
this->name = "defaultName";
}
SoftwaresConfigurations.h (who call the contructor of Software) :
#include "Software.h"
class SoftwaresConfigurations {
public:
SoftwaresConfigurations();
}
SoftwaresConfiguration.cpp :
#include "SoftwaresConfigurations.h"
SoftwaresConfigurations::SoftwaresConfigurations(){
Software software = Software();
}
You have fallen into the trap that is FILE(GLOB ...).
Re-running CMake should fix this, but you should probably move away from using GLOB to collect your source files. For example, you can list them explicitly as follows:
set(SOURCES src/main.cpp src/Softwares.cpp src/SoftwaresConfigurations.cpp)
I will explain what happened below.
The official documentation says the following:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
So what probably happened is that you created the project with just one source file. CMake ran the GLOB at configuration-time and found only the one .cpp file.
Then, you added two files (which CMake did not know about) and added the #include to your SoftwaresConfiguration.cpp. This triggers a rebuild. However, since CMake does not know about Softwares.cpp, it does not build that file and the linker produces an unreferenced symbol.
Related
I can run and compile with no problem, but VSCode Intellisense is saying that it cannot open source file boost/asio.hpp (even tho it obviously can) and is marking it as an error all the time, I want to know why its doing it and how to fix it
I have the following directory:
root/
include/
atr_include.hpp
user_interface.hpp
src/
user_interface.cpp
CMakeList.txt
main.cpp
CMakeList.txt
With CMakeList.txt:
#CMake minimum version
cmake_minimum_required(VERSION 3.0.0)
#C++ Standard version
set(CMAKE_CXX_STANDARD 20)
### Searches for the VCPKG
if(DEFINED ENV{VCPKG_ROOT})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
endif()
project(main LANGUAGES CXX VERSION 0.1.0 )
find_package(Boost COMPONENTS system json REQUIRED)
add_executable(${PROJECT_NAME} main.cpp)
include_directories(include)
link_directories(src)
add_subdirectory(src)
link_libraries(atr_lib)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
endif()
if(MSVC OR MSYS OR MINGW)
target_link_libraries(${PROJECT_NAME} ws2_32)
endif()
src/CMakeList:
add_library(atr_lib STATIC user_interface.cpp)
include/atr_include.hpp:
#include <boost/asio.hpp>
#include <chrono>
#include <iostream>
#include <math.h>
#include <mutex>
#include <thread>
include/user_interface.hpp:
#include "atr_include.hpp"
class UserInterface
{
private:
public:
};
src/user_interface.cpp:
#include <user_interface.hpp>
main.cpp:
#include <user_interface.hpp>
int main() { return 0; }
I had the same problem and it was related to the incorrect configuration of the IntelliSense Configuration Provider item.
"configurations": [
{
...
"configurationProvider": "ms-vscode.cmake-tools"
...
}
The previous value corresponded to another Cmake extension that was no longer installed. After changing the value to ms-vscode.cmake-tools (I have the "CMake Tools" extension installed), IntelliSense started working correctly. Also boost headers includes correctly without errors from VS Code.
VSCode is not a C++ compiler. It is (mostly) a text editor, and some development tools. It merely runs some C++ compiler in order to actually compile and build C++ code.
Your actual C++ compiler is the final and ultimate authority on where it can find various header files.
For whatever reason, your VSCode configuration does not know where boost's header files are installed, so that's what it tells you. Your compiler knows, but that's your compiler, not VSCode.
So, no, VSCode really can't open or find these header files. Your question was:
I want to know why its doing it
Because it simply doesn't know. It's not your C++ compiler, and it doesn't automatically know where all header files are installed.
and how to fix it
That ...depends on your very, very specific computer, operating system (VSCode is available for multiple operating systems), whichever C++ compiler you are actually using with VSCode, and how exactly you are using VSCode (for a brief time, for example, I used VSCode to edit files that weren't even on the same computer, but accessed via ssh). Each one of these factors affects the how everything works, together.
If you know where boost's header files are installed, this may simply be a matter of digging through VSCode's configuration settings, there must be a setting somewhere that tells boost which directories contain header files to search for. If you don't know where boost's header files are installed, your first step will be to figure that part out, before anything else can be done.
Answer is found. To save your time from reading alot:
Useful Document Here:
https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/Exporting-and-Importing-Targets
The working CMakeLists.txt is like this:
cmake_minimum_required(VERSION 3.10)
project(Test VERSION 1.0)
add_library(Lib SHARED IMPORTED)
set_property(TARGET Lib PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/lib.dll")
set_property(TARGET Lib PROPERTY IMPORTED_IMPLIB "${PROJECT_SOURCE_DIR}/lib.dll.a") //Notice: lib.lib here if you are using VS building system.
add_executable(App app.cxx)
target_link_libraries(App Lib)
Most tutorial online will assume you are using MS VS build system. Thus they will keep talking about importing a "*.lib" file.
If you use GCC(MinGW) like me, the actually file you are looking for is "*.dll.a"
Edit in Sep.17
No it's not right. We are using a DLL. And a DLL should not affect the compiling.
DLL should be whenever you want to place them into the folder which the .exe required instead of compiling check for header.
But we are trying to unpack a header from a dll.
There must be something wrong with this workflow.
CMake and GCC
I cannot use any IDE nor VS Build Tool due to the lack of license in my company.
Thus I'll have to learn about CMake + GCC for an open-sourced compile environment.
I could compile app and static library correctly now. But stuck in dll linkage.
This should be a simple one but since I can't find any sample on Google thus I need your help to correction the CMake workflow in this DLL linking job. Thanks.
Or maybe any hyperlink where could find a right direction.
As I know, I could simply add the dll library in IDE like VisualStudio and it will do all the magic to exchange it into something containing a header file.
I must missed this part in CMake.
My Step:
Compile a dll
Compile an legacy app without dll
Recreate the app with function linked from dll (BOOM!)
Detailed codes below:
Step 1: Compile a dll
Code in Test.h:
#pragma once
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
extern "C" TEST_API int helloworld();
Code in Test.cxx:
#include <iostream>
#include "Test.h"
int helloworld() {
std::cout << "I hate HelloWorld\n";
return 0;
}
Code in CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(Test)
include(GenerateExportHeader)
add_library(Test SHARED Test.cxx)
generate_export_header(Test)
Compile it. Get a "libTest.dll". Good.
Step 2: Compile a legacy app without a dll
Let's skip it. Just a hello world console app. Nothing special.
Compile finished. Good to go.
Step 3: Recreate the app with linked dll
I've tried so many sample from google but no luck till now.
I've tried the library's name both "Test" and "libTest".
I've tried to put the dll directly in both ${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR}, and make an add_subdirectory(libStore).
I've tried to use find_package(Test/libTest).
Thus I think there should be something incorrect in my cmake and source code.
Code in App.cxx:
#include <iostream>
#include "Test.h" //Also tried "libTest.h"
int main() {
std::cout << helloworld();
getchar();
return 0;
}
Attempt 1:
Put libTest.dll under sub directory "/Lib"
Code in root CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(App VERSION 1.0)
include_directories("${PROJECT_SOURCE_DIR}/Lib")
add_subdirecotry(Lib)
add_executable(App App.cxx)
target_link_libraries(App libTest) //Tried both Test and libTest
Code in /Lib CMakeLists.txt:
add_library(libTest libTest.dll)
set_target_properties(libTest PROPERTIES LINKER_LANGUAGE C)
Build result:
Fatal Error: Test.h(libTest.h): No such file or directory.
Attempt 2:
Put libTest.dll directly in source directory (${PROJECT_SOURCE_DIR})
Code in CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(App VERSION 1.0)
include_directories("${PROJECT_SOURCE_DIR}")
add_executable(App App.cxx)
target_link_libraries(App libTest) //Tried both Test and libTest
Build Result:
Fatal Error: Test.h(libTest.h): No such file or directory.
Attempt 3:
Same with Attempt 2 but add a find_package(libTest) function.
cmake_minimum_required(VERSION 3.10)
project(App VERSION 1.0)
include_directories("${PROJECT_SOURCE_DIR}")
find_package(libTest)
add_executable(App App.cxx)
target_link_libraries(App libTest) //Tried both Test and libTest
CMake Warning:
Could not find a package configuration file provided by "libTest" with any of the following names:
libTestConfig.cmake
libTest-config.cmake
Created an empty file names libTestConfig.cmake in source directory.
Build Result:
Fatal Error: Test.h(libTest.h): No such file or directory.
BOOM!
At last, I found the answer here:
https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/Exporting-and-Importing-Targets
First:
All of the code in my old attempts are assuming you have your source code in your project folder.
If you want to import a DLL you get from outside, the actually CMakeLists.txt should look like this:
cmake_minimum_required(VERSION 3.10)
project(Test VERSION 1.0)
add_library(Lib SHARED IMPORTED)
set_property(TARGET Lib PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/lib.dll")
set_property(TARGET Lib PROPERTY IMPORTED_IMPLIB "${PROJECT_SOURCE_DIR}/lib.dll.a") //Notice: lib.lib here if you are using VS building system.
add_executable(App app.cxx)
target_link_libraries(App Lib)
Second:
Almost all the tutorial online will assume you are using MS VS build system. Thus they will keep talking about importing a "*.lib" file.
Which will be a big mislead and makes you meaninglessly tracing the non-exist lib file and confuse it with the dll file itself.
If you use GCC(MinGW) like me, the actually file you are looking for is "lib.dll.a"
I think the problem may be here:
include_directories("${PROJECT_SOURCE_DIR}")
Rather than having an issue finding the DLL itself, it seems like cmake is simply having an issue finding the Test.h (or libTest.h) header file. Try putting the DLL's header file in a path that's specified via cmake's "include_directories".
I'm attempting to run a cmake hello world program on Windows 7 x64 with both Visual Studio 2010 and Cygwin, but can't seem to get either to work. My directory structure is as follows:
HelloWorld
-- CMakeLists.txt
-- src/
-- -- CMakeLists.txt
-- -- main.cpp
-- build/
I do a cd build followed by a cmake .., and get an error stating that
CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".
However, if I change the extension of main.cpp to main.c both on my filsystem and in src/CMakeLists.txt everything works as expected. This is the case running from both the Visual Studio Command Prompt (Visual Studio Solution Generator) and the Cygwin Terminal (Unix Makefiles Generator).
Any idea why this code wouldn't work?
CMakeLists.txt
PROJECT(HelloWorld C)
cmake_minimum_required(VERSION 2.8)
# include the cmake modules directory
set(CMAKE_MODULE_PATH ${HelloWorld_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
add_subdirectory(src)
src/CMakeLists.txt
# Include the directory itself as a path to include directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Create a variable called helloworld_SOURCES containing all .cpp files:
set(HelloWorld_SOURCES main.cpp)
# Create an executable file called helloworld from sources:
add_executable(hello ${HelloWorld_SOURCES })
src/main.cpp
int main()
{
return 0;
}
I also got the error you mention:
CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".
In my case this was due to having C++ files with the .cc extension.
If CMake is unable to determine the language of the code correctly you can use the following:
set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)
The accepted answer that suggests appending the language to the project() statement simply adds more strict checking for what language is used (according to the documentation), but it wasn't helpful to me:
Optionally you can specify which languages your project supports.
Example languages are CXX (i.e. C++), C, Fortran, etc. By default C
and CXX are enabled. E.g. if you do not have a C++ compiler, you can
disable the check for it by explicitly listing the languages you want
to support, e.g. C. By using the special language "NONE" all checks
for any language can be disabled. If a variable exists called
CMAKE_PROJECT__INCLUDE_FILE, the file pointed to by that
variable will be included as the last step of the project command.
In my case, it was just because there were no source file in the target. All of my code was a template with the source code in the header file. Adding an empty file.cpp solved the problem.
Try changing
PROJECT(HelloWorld C)
into
PROJECT(HelloWorld C CXX)
or just
PROJECT(HelloWorld)
See: https://cmake.org/cmake/help/latest/command/project.html
Confusing as it might be, the error also happens when a cpp file included in the project does not exist.
If you list your source files in CMakeLists.txt and mistakenly type a file name then you get this error.
I want to add another solution in case a library without any source files shall be build. Such libraries are also known as header only libraries. By default add_library expects at least one source file added or otherwise the mentioned error occurs. Since header only libraries are quite common, cmake has the INTERFACE keyword to build such libraries. The INTERFACE keyword is used as shown below and it eliminates the need for empty source files added to the library.
add_library(myLibrary INTERFACE)
target_include_directories(myLibrary INTERFACE {CMAKE_CURRENT_SOURCE_DIR})
The example above would build a header only library including all header files in the same directory as the CMakeLists.txt. Replace {CMAKE_CURRENT_SOURCE_DIR} with a path in case your header files are in a different directory than the CMakeLists.txt file.
Have a look at this blog post or the cmake documentation for further info regarding header only libraries and cmake.
A bit unrelated answer to OP but for people like me with a somewhat similar problem.
Use Case: Ubuntu (C, Clion, Auto-completion):
I had the same error,
CMake Error: Cannot determine link language for target "hello".
set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) help fixes that problem but the headers aren't included to the project and the autocompletion wont work.
This is what i had
cmake_minimum_required(VERSION 3.5)
project(hello)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES ./)
add_executable(hello ${SOURCE_FILES})
set_target_properties(hello PROPERTIES LINKER_LANGUAGE C)
No errors but not what i needed, i realized including a single file as source will get me autocompletion as well as it will set the linker to C.
cmake_minimum_required(VERSION 3.5)
project(hello)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES ./1_helloworld.c)
add_executable(hello ${SOURCE_FILES})
I also faced a similar error while compiling my C-based code. I fixed the issue by correcting the source file path in my cmake file. Please check the source file path of each source file mentioned in your cmake file. This might help you too.
Simply check the path to source file. (to the respective cpp)
By default the JNI Native folder is named as jni . Renaming it to cpp fixed the issue
I managed to solve mine, by changing
add_executable(file1.cpp)
to
add_executable(ProjectName file1.cpp)
I'm trying to migrate from Visual Studio towards Jetbrains' (awesome) CLion IDE which uses CMake to organize the projects.
Until now, the transition has been smooth: creating CMake projects and importing them into CLion is easy, and I can begin coding on one plateform then continue on another one without problems.
However, one aspect of Visual Studio that I couldn't find an equivalent to in CMake is property sheets: I use them mainly for holding the include directories' paths and the linking libs for libraries (i.e. one .vsprops file for each library, e.g. OpenCV.vsprops, Boost.vsprops, etc.).
This way, in VS, I could share a library's .vsprops file between different projects without having to configure the paths/libs each time.
Does CMake have a similar mechanism to Visual Studio's property sheets ? How is it possible to store a library's includes/libs in a CMake-parsable file then "import" it in CMakeLists.txt in order to link against the library ?
Basically, what I want to do is:
Create a "cmake property sheet" (for lack of a better name) for a given library.
Then, in CMakeLists.txt, write something like link_target_to_libs(myTarget "path/to/propertySheet1" "path/to/propertySheet2" ...) .
In CMake, libraries can export a package with IMPORTED targets which other buildsystems import using find_package:
http://www.cmake.org/cmake/help/v3.1/manual/cmake-packages.7.html
http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html
http://www.cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#imported-targets
Instead of 'linking to property sheets', you link to the IMPORTED targets.
target_link_libraries(myTarget Dep1::Dep1 Dep2::Dep2)
Not all libraries create IMPORTED targets, and not all provide cmake config-file packages. In those cases (including OpenCV and Boost), CMake provides find modules:
http://www.cmake.org/cmake/help/v3.0/manual/cmake-developer.7.html#find-modules
which you use with find_package and link to the contents of variables.
Since I really want to make the libraries' inclusion/linking into a one-line command, and as far as my (basic) knowledge of CMake goes, I think that some compromise should be made -- mainly sharing the target name's variable between CMakeLists.txt and the "property sheets". So this is my solution... until someone proposes a simpler/cleaner one:
A CMake property sheet is a .cmake text file,
A well-known variable name --TARGET-- designates the target (i.e. the first argument of add_executable()),
Aside from library-specific commands, a .cmake file contains a call to target_include_directories(${TARGET} PRIVATE ${PATH_TO_INCLUDE_DIR}) and target_link_libraries(${TARGET} ${LIST_OF_LIBS}),
In order to use/link against a library, call include("path/to/.cmake") in CMakeLists.txt.
I have successfully built and executed a simple program that uses X11 and OpenCV with the following files:
x11.cmake
target_include_directories(${TARGET} PRIVATE "/usr/include/X11")
target_link_libraries(${TARGET} "/usr/lib/x86_64-linux-gnu/libX11.so")
opencv.cmake
# OpenCV-specific stuff
set(OpenCV_DIR "/PATH/TO/OPENCV/INSTALL/DIR/share/OpenCV") # path to OpenCVConfig.cmake
find_package(OpenCV REQUIRED)
# include path
target_include_directories(${TARGET} PRIVATE ${OpenCV_INCLUDE_DIRS})
# linking libs
target_link_libraries(${TARGET} opencv_world opencv_ts)
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.4)
project(hello_clion)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
## hello-clion ##############################
# make a new target name
set(TARGET hello-clion)
# find sources
file(GLOB_RECURSE SOURCE_FILES "src/*.cpp" "src/*.hpp")
# declare a target
add_executable(${TARGET} ${SOURCE_FILES})
# link the libraries (to the last-declared ${TARGET}, which should be the last-added executable)
include("x11.cmake")
include("opencv.cmake")
#############################################
main.cpp
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <thread>
#include <opencv2/opencv.hpp>
#include <Xlib.h>
int main_x11()
{
// adapted from: http://rosettacode.org/wiki/Window_creation/X11#Xlib
}
int main_ocv()
{
// adapted from: http://docs.opencv.org/doc/tutorials/introduction/display_image/display_image.html#source-code
}
int main()
{
using namespace std;
thread tocv(main_ocv);
thread tx11(main_x11);
tocv.join();
tx11.join();
return 0;
}
Now, each time I want to use OpenCV in a project/program, I just have to put include("opencv.cmake") in the corresponding CMakeLists.txt.
This seems to work great, but there could certainly be problems I haven't discovered. (I was worried multiple macros adding the same target_link_libraries would cause "already defined" linking errors , but at least g++ 5.1.0 handles being given the same library name multiple times without error.)
In root CMakeLists.txt, BEFORE add_subdirectory() calls or globs, include:
macro(USES_WX)
include_directories(SYSTEM /usr/local/include/wx-3.0)
include_directories(SYSTEM /usr/local/lib/wx/include/gtk3-unicode-3.0)
link_directories(/usr/local/lib)
add_definitions(-D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread)
target_link_libraries(${TARGET} pthread wx_gtk3u_xrc-3.0 wx_gtk3u_html-3.0 wx_gtk3u_qa-3.0 wx_gtk3u_adv-3.0 wx_gtk3u_core-3.0 wx_baseu_xml-3.0 wx_baseu_net-3.0 wx_baseu-3.0)
endmacro()
(You can make the macro more fancy, like checking for if CMAKE_BUILD_TYPE is "Debug" or "Release" to link to the appropriate libraries, vary preprocessor definitions, etc. See http://www.cmake.org/cmake/help/v3.0/command/if.html)
And have your project's CMakeLists.txt be like this:
set(TARGET myProgramName)
add_executable(${TARGET} myProgramName.cpp)
USES_WX()
^^ The macro call MUST be after add_executable()
And, if you want multiple target support, modify the line in the root CMakeLists.txt section shown above to:
...
target_link_libraries(${ARGV0} pthread wx_gtk3u_xrc-3.0 ...)
...
And have your project's CMakeLists.txt be like this (less lines, but more chance for error):
add_executable(myProgramName myProgramName.cpp)
USES_WX(myProgramName)
I'm attempting to run a cmake hello world program on Windows 7 x64 with both Visual Studio 2010 and Cygwin, but can't seem to get either to work. My directory structure is as follows:
HelloWorld
-- CMakeLists.txt
-- src/
-- -- CMakeLists.txt
-- -- main.cpp
-- build/
I do a cd build followed by a cmake .., and get an error stating that
CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".
However, if I change the extension of main.cpp to main.c both on my filsystem and in src/CMakeLists.txt everything works as expected. This is the case running from both the Visual Studio Command Prompt (Visual Studio Solution Generator) and the Cygwin Terminal (Unix Makefiles Generator).
Any idea why this code wouldn't work?
CMakeLists.txt
PROJECT(HelloWorld C)
cmake_minimum_required(VERSION 2.8)
# include the cmake modules directory
set(CMAKE_MODULE_PATH ${HelloWorld_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
add_subdirectory(src)
src/CMakeLists.txt
# Include the directory itself as a path to include directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Create a variable called helloworld_SOURCES containing all .cpp files:
set(HelloWorld_SOURCES main.cpp)
# Create an executable file called helloworld from sources:
add_executable(hello ${HelloWorld_SOURCES })
src/main.cpp
int main()
{
return 0;
}
I also got the error you mention:
CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".
In my case this was due to having C++ files with the .cc extension.
If CMake is unable to determine the language of the code correctly you can use the following:
set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)
The accepted answer that suggests appending the language to the project() statement simply adds more strict checking for what language is used (according to the documentation), but it wasn't helpful to me:
Optionally you can specify which languages your project supports.
Example languages are CXX (i.e. C++), C, Fortran, etc. By default C
and CXX are enabled. E.g. if you do not have a C++ compiler, you can
disable the check for it by explicitly listing the languages you want
to support, e.g. C. By using the special language "NONE" all checks
for any language can be disabled. If a variable exists called
CMAKE_PROJECT__INCLUDE_FILE, the file pointed to by that
variable will be included as the last step of the project command.
In my case, it was just because there were no source file in the target. All of my code was a template with the source code in the header file. Adding an empty file.cpp solved the problem.
Try changing
PROJECT(HelloWorld C)
into
PROJECT(HelloWorld C CXX)
or just
PROJECT(HelloWorld)
See: https://cmake.org/cmake/help/latest/command/project.html
Confusing as it might be, the error also happens when a cpp file included in the project does not exist.
If you list your source files in CMakeLists.txt and mistakenly type a file name then you get this error.
I want to add another solution in case a library without any source files shall be build. Such libraries are also known as header only libraries. By default add_library expects at least one source file added or otherwise the mentioned error occurs. Since header only libraries are quite common, cmake has the INTERFACE keyword to build such libraries. The INTERFACE keyword is used as shown below and it eliminates the need for empty source files added to the library.
add_library(myLibrary INTERFACE)
target_include_directories(myLibrary INTERFACE {CMAKE_CURRENT_SOURCE_DIR})
The example above would build a header only library including all header files in the same directory as the CMakeLists.txt. Replace {CMAKE_CURRENT_SOURCE_DIR} with a path in case your header files are in a different directory than the CMakeLists.txt file.
Have a look at this blog post or the cmake documentation for further info regarding header only libraries and cmake.
A bit unrelated answer to OP but for people like me with a somewhat similar problem.
Use Case: Ubuntu (C, Clion, Auto-completion):
I had the same error,
CMake Error: Cannot determine link language for target "hello".
set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) help fixes that problem but the headers aren't included to the project and the autocompletion wont work.
This is what i had
cmake_minimum_required(VERSION 3.5)
project(hello)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES ./)
add_executable(hello ${SOURCE_FILES})
set_target_properties(hello PROPERTIES LINKER_LANGUAGE C)
No errors but not what i needed, i realized including a single file as source will get me autocompletion as well as it will set the linker to C.
cmake_minimum_required(VERSION 3.5)
project(hello)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES ./1_helloworld.c)
add_executable(hello ${SOURCE_FILES})
I also faced a similar error while compiling my C-based code. I fixed the issue by correcting the source file path in my cmake file. Please check the source file path of each source file mentioned in your cmake file. This might help you too.
Simply check the path to source file. (to the respective cpp)
By default the JNI Native folder is named as jni . Renaming it to cpp fixed the issue
I managed to solve mine, by changing
add_executable(file1.cpp)
to
add_executable(ProjectName file1.cpp)