CMake không thể xác định ngôn ngữ trình liên kết với C ++


89

Tôi đang cố gắng chạy chương trình cmake hello world trên Windows 7 x64 với cả Visual Studio 2010 và Cygwin, nhưng dường như không thể hoạt động. Cấu trúc thư mục của tôi như sau:

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

Tôi thực hiện cd buildtheo sau là a cmake ..và gặp lỗi khi nói rằng

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

Tuy nhiên, nếu tôi thay đổi phần mở rộng của main.cpp thành main.c cả trên hệ thống lọc của tôi và src/CMakeLists.txtmọi thứ đều hoạt động như mong đợi. Đây là trường hợp chạy từ cả Visual Studio Command Prompt (Visual Studio Solution Generator) và Cygwin Terminal (Unix Makefiles Generator).

Bất kỳ ý tưởng tại sao mã này không hoạt động?

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;
}

"[...] nếu tôi thay đổi phần mở rộng của main.cpp [...]" Bạn thay đổi nó thành gì? .cc?
JAB

Giáo sư. Bỏ lại điều đó một cách tình cờ. Tôi thay đổi nó thành '.c'. Đã chỉnh sửa trong bài gốc. Nó gần như khiến tôi nghĩ rằng không có trình biên dịch cpp hoặc một cái gì đó tương tự, nhưng g ++ thì không ổn và studio trực quan cũng không gặp vấn đề với c ++.
Chris Covert

Câu trả lời:



182

Tôi cũng nhận được lỗi mà bạn đề cập:

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

Trong trường hợp của tôi, điều này là do có tệp C ++ với .ccphần mở rộng.

Nếu CMake không thể xác định chính xác ngôn ngữ của mã, bạn có thể sử dụng các cách sau:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

Câu trả lời được chấp nhận đề xuất thêm ngôn ngữ vào project()câu lệnh chỉ đơn giản là thêm kiểm tra chặt chẽ hơn cho ngôn ngữ nào được sử dụng (theo tài liệu), nhưng nó không hữu ích đối với tôi:

Theo tùy chọn, bạn có thể chỉ định ngôn ngữ mà dự án của bạn hỗ trợ. Các ngôn ngữ ví dụ là CXX (tức là C ++), C, Fortran, v.v. Theo mặc định, C và CXX được bật. Ví dụ: nếu bạn không có trình biên dịch C ++, bạn có thể tắt kiểm tra nó bằng cách liệt kê rõ ràng các ngôn ngữ bạn muốn hỗ trợ, ví dụ: C. Bằng cách sử dụng ngôn ngữ đặc biệt "KHÔNG", tất cả các kiểm tra cho bất kỳ ngôn ngữ nào đều có thể bị vô hiệu hóa. Nếu tồn tại một biến được gọi là CMAKE_PROJECT__INCLUDE_FILE, tệp được trỏ đến bởi biến đó sẽ được đưa vào bước cuối cùng của lệnh dự án.


Trong trường hợp của tôi, tệp của tôi có phần mở rộng .hpp. Điều này đã giải quyết nó!
brawner

Đối với tôi cũng vậy, tệp .hpp và điều này đã sửa nó.
KulaGGin

68

Trong trường hợp của tôi, đó chỉ là do không có tệp nguồn nào trong đích. Tất cả thư viện của tôi là mẫu với mã nguồn trong tiêu đề. Thêm một tệp trống .cpp đã giải quyết được vấn đề.


6
đặt thuộc tính mục tiêu cũng hoạt động đối với vấn đề không có tệp cpp.
Denise Skidmore

1
Kudo cho tiền boa. Tôi cũng đã quên di chuyển các nguồn của mình sang srcthư mục con tương ứng của cmakedự án mới tạo của tôi (một thư viện được chia sẻ) và về cơ bản đây là nguyên nhân của toàn bộ vấn đề. Trong những trường hợp như vậy, người ta thực sự đánh giá cao việc có một trình hướng dẫn chăm sóc cấu trúc cmakedự án của bạn . : D
rbaleksandar

Lý do tương tự ở đây (sao chép-dán nhầm). Cảm ơn!
Vivit

2
Mẹo hữu ích. Ngay cả khi "thư viện" của bạn chỉ là tiêu đề, bạn nên tạo một tệp .cpp tương #includeứng với mỗi tệp. Mặc dù sẽ không có đầu ra khi thư viện của bạn được biên dịch, nhưng nó sẽ thực hiện kiểm tra cú pháp tệp của bạn và cũng kiểm tra các phụ thuộc tiêu đề (ví dụ: tiêu đề hệ thống) mà bạn có thể đã bỏ qua.
Mark Lakata

Nó đơn giản như vậy. Lỗi đánh máy trong đường dẫn dẫn đến không có tệp * .cpp nào trong nguồn. Tất cả đều ổn sau đó. Cảm ơn bạn!
Rahul Das

17

Nó có thể gây nhầm lẫn, lỗi cũng xảy ra khi tệp cpp có trong dự án không tồn tại.

Nếu bạn liệt kê các tệp nguồn của mình trong CMakeLists.txt và nhập nhầm tên tệp thì bạn sẽ gặp lỗi này.


Hãy làm điều này như trong phần bình luận.
Virb

1
Câu trả lời này hoạt động như một câu trả lời riêng vì nó độc lập với những gì các câu trả lời khác đã nói. Ngoài ra điều này đã khắc phục sự cố của tôi.
Czarking

5

Một câu trả lời hơi không liên quan đến OP nhưng đối với những người như tôi với một vấn đề tương tự.

Trường hợp sử dụng: Ubuntu (C, Clion, Tự động hoàn thành):

Tôi đã có những lỗi giống nhau,

Lỗi CMake: Không thể xác định ngôn ngữ liên kết cho mục tiêu "xin chào".

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) giúp khắc phục sự cố đó nhưng tiêu đề không được đưa vào dự án và tính năng tự động hoàn thành sẽ không hoạt động.

Đây là những gì tôi đã có

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)

Không có lỗi nhưng không phải những gì tôi cần, tôi nhận ra rằng bao gồm một tệp duy nhất làm nguồn sẽ giúp tôi tự động hoàn thành cũng như nó sẽ đặt trình liên kết thành 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})

Chỉ nhận thấy rằng bạn đang sử dụng CXX_FLAGS để đặt phiên bản chuẩn C ++ và nghĩ rằng tôi sẽ đề cập đến biến CXX_STANDARD, biến này theo tôi là cách được đề xuất cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html và nên có sẵn trong cmake 3,5
Chris Covert

2

Tôi cũng gặp phải lỗi tương tự khi biên dịch mã dựa trên C của mình. Tôi đã khắc phục sự cố bằng cách sửa đường dẫn tệp nguồn trong cmaketệp của mình . Vui lòng kiểm tra đường dẫn tệp nguồn của mỗi tệp nguồn được đề cập trong cmaketệp của bạn . Điều này cũng có thể giúp bạn.


0

Theo mặc định, thư mục JNI Native được đặt tên là jni . Đổi tên nó thành cpp đã khắc phục sự cố


0

Tôi muốn thêm một giải pháp khác trong trường hợp một thư viện không có bất kỳ tệp nguồn nào sẽ được xây dựng. Các thư viện như vậy còn được gọi là thư viện chỉ tiêu đề . Theo mặc định, add_libraryít nhất một tệp nguồn được thêm vào, nếu không sẽ xảy ra lỗi được đề cập. Vì các thư viện chỉ tiêu đề khá phổ biến, nên cmake có INTERFACEtừ khóa để xây dựng các thư viện như vậy. Các INTERFACEtừ khóa được sử dụng như hình dưới đây và nó giúp loại bỏ sự cần thiết cho các tập tin nguồn có sản phẩm nào được bổ sung vào thư viện.

add_library(myLibrary INTERFACE)
target_include_directories(myLibrary INTERFACE {CMAKE_CURRENT_SOURCE_DIR})

Ví dụ trên sẽ xây dựng một thư viện chỉ tiêu đề bao gồm tất cả các tệp tiêu đề trong cùng một thư mục với CMakeLists.txt. Thay thế {CMAKE_CURRENT_SOURCE_DIR}bằng một đường dẫn trong trường hợp các tệp tiêu đề của bạn nằm trong một thư mục khác với tệp CMakeLists.txt.

Hãy xem bài đăng trên blog này hoặc tài liệu cmake để biết thêm thông tin về các thư viện chỉ dành cho tiêu đề và cmake.


-2

Tôi đã giải quyết được vấn đề của mình bằng cách thay đổi

add_executable(file1.cpp)

đến

add_executable(ProjectName file1.cpp)

-2

Trong trường hợp của tôi, việc triển khai một hàm thành viên của một lớp trong tệp tiêu đề gây ra lỗi này. Giao diện tách biệt (trong tệp xh) và triển khai (trong tệp x.cpp) giải quyết vấn đề.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.