CMake tidak dapat menentukan bahasa penaut dengan C ++

90

Saya mencoba menjalankan program cmake hello world pada Windows 7 x64 dengan Visual Studio 2010 dan Cygwin, tetapi sepertinya tidak bisa keduanya bekerja. Struktur direktori saya adalah sebagai berikut:

HelloWorld
-- CMakeLists.txt
-- src/
-- -- CMakeLists.txt
-- -- main.cpp
-- build/

Saya melakukan cd builddiikuti dengan a cmake .., dan mendapatkan kesalahan yang menyatakan itu

CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".

Namun, jika saya mengubah ekstensi main.cpp menjadi main.c baik di filsystem saya dan src/CMakeLists.txtsemuanya berfungsi seperti yang diharapkan. Ini adalah kasus yang berjalan dari Visual Studio Command Prompt (Visual Studio Solution Generator) dan Cygwin Terminal (Unix Makefiles Generator).

Tahu mengapa kode ini tidak berfungsi?

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;
}
Chris Covert
sumber
"[...] jika saya mengubah ekstensi main.cpp [...]" Apa yang Anda ubah? .cc?
JAB
Ups. Tidak sengaja meninggalkannya. Saya mengubahnya menjadi '.c'. Diedit di postingan asli. Ini hampir membuat saya berpikir bahwa tidak ada kompiler cpp atau semacamnya, tetapi g ++ tidak di-insall dan studio visual seharusnya tidak memiliki masalah dengan c ++ juga.
Chris Covert

Jawaban:

185

Saya juga mendapat kesalahan yang Anda sebutkan:

CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".

Dalam kasus saya ini karena memiliki file C ++ dengan .ccekstensi.

Jika CMake tidak dapat menentukan bahasa kode dengan benar, Anda dapat menggunakan yang berikut ini:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

Jawaban yang diterima yang menyarankan untuk menambahkan bahasa ke project()pernyataan hanya menambahkan pemeriksaan yang lebih ketat untuk bahasa apa yang digunakan (menurut dokumentasi), tetapi itu tidak membantu saya:

Secara opsional, Anda dapat menentukan bahasa yang didukung proyek Anda. Contoh bahasa adalah CXX (yaitu C ++), C, Fortran, dll. Secara default C dan CXX diaktifkan. Misalnya jika Anda tidak memiliki kompilator C ++, Anda dapat menonaktifkan pemeriksaannya dengan mencantumkan secara eksplisit bahasa yang ingin Anda dukung, misalnya C. Dengan menggunakan bahasa khusus "NONE" semua pemeriksaan untuk bahasa apa pun dapat dinonaktifkan. Jika ada variabel yang disebut CMAKE_PROJECT__INCLUDE_FILE, file yang ditunjukkan oleh variabel itu akan dimasukkan sebagai langkah terakhir dari perintah proyek.

Joakim
sumber
Dalam kasus saya, file saya memiliki ekstensi .hpp. Ini menyelesaikannya!
petarung
Sama untuk saya, file .hpp dan ini memperbaikinya.
KulaGGin
71

Dalam kasus saya, itu hanya karena tidak ada file sumber di target. Semua perpustakaan saya adalah template dengan kode sumber di header. Menambahkan file kosong.cpp memecahkan masalah.

Moebius
sumber
6
mengatur properti target juga berfungsi untuk masalah file cpp.
Denise Skidmore
1
Kudos untuk tipnya. Saya juga lupa untuk memindahkan sumber saya ke srcsubdirektori masing-masing dari cmakeproyek yang baru saya buat (perpustakaan bersama) dan ini pada dasarnya adalah penyebab dari seluruh masalah. Dalam kasus seperti itu, seseorang benar-benar menghargai memiliki wizard untuk menjaga struktur cmakeproyek Anda . : D
rbaleksandar
Alasan yang sama di sini (kesalahan salin-tempel). Terima kasih!
Vivit
2
Tip yang berguna. Meskipun "perpustakaan" Anda hanya berupa header, Anda harus membuat satu file .cpp yang melakukan a #includeuntuk setiap file. Meskipun tidak akan ada keluaran saat perpustakaan Anda dikompilasi, itu akan melakukan pemeriksaan sintaks file Anda, dan juga memeriksa dependensi header (misalnya header sistem) yang mungkin Anda lewatkan.
Mark Lakata
Sesederhana itu. Salah ketik di jalur menyebabkan tidak ada file * .cpp di sumber. Semua baik-baik saja setelah itu. Terima kasih!
Rahul Das
17

Meskipun membingungkan, kesalahan juga terjadi ketika file cpp yang disertakan dalam proyek tidak ada.

Jika Anda mendaftarkan file sumber Anda di CMakeLists.txt dan salah mengetik nama file maka Anda mendapatkan kesalahan ini.

Jolly Roger
sumber
Tolong buat ini seperti di bagian komentar.
Virb
1
Ini berfungsi sebagai jawaban sendiri karena tidak tergantung pada apa yang dikatakan jawaban lain. Ini juga memperbaiki masalah saya.
Czarking
5

Jawaban yang agak tidak terkait dengan OP tetapi untuk orang seperti saya dengan masalah yang agak mirip.

Kasus Penggunaan: Ubuntu (C, Clion, Penyelesaian Otomatis):

Saya mengalami kesalahan yang sama,

Kesalahan CMake: Tidak dapat menentukan bahasa tautan untuk target "hello".

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) membantu memperbaiki masalah itu tetapi header tidak disertakan ke proyek dan pelengkapan otomatis tidak akan berfungsi.

Inilah yang saya miliki

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)

Tidak ada kesalahan tetapi bukan yang saya butuhkan, saya menyadari bahwa memasukkan satu file sebagai sumber akan membuat saya pelengkapan otomatis serta akan mengatur linker ke 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})
f_i
sumber
Just noticed that you're using CXX_FLAGS to set the C++ standard version, and thought I'd mention the CXX_STANDARD variable, which I think is the recommended way cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html and should be available in cmake 3.5
Chris Covert
2

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.

user2999709
sumber
1

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.

zhm
sumber
0

By default the JNI Native folder is named as jni . Renaming it to cpp fixed the issue

HimalayanCoder
sumber
-2

I managed to solve mine, by changing

add_executable(file1.cpp)

to

add_executable(ProjectName file1.cpp)
AKJ
sumber
-2

In my case, implementing a member function of a class in a header file cause this error. Separating interface (in x.h file) and implementation (in x.cpp file) solves the problem.

adembudak
sumber