CMake não consegue determinar a linguagem do linker com C ++

91

Estou tentando executar um programa cmake hello world no Windows 7 x64 com o Visual Studio 2010 e o Cygwin, mas não consigo fazer nenhum dos dois funcionar. Minha estrutura de diretório é a seguinte:

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

Eu faço a cd buildseguido por a cmake ..e recebo um erro informando que

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

No entanto, se eu alterar a extensão de main.cpp para main.c, tanto no meu sistema de arquivos quanto em src/CMakeLists.txttudo funcionará conforme o esperado. Esse é o caso em execução no Prompt de Comando do Visual Studio (Visual Studio Solution Generator) e no Cygwin Terminal (Unix Makefiles Generator).

Alguma ideia de por que esse código não funcionaria?

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
fonte
"[...] se eu mudar a extensão de main.cpp [...]" Para que você muda? .cc?
JAB
opa. Deixei isso de fora por acidente. Eu mudo para '.c'. Editado na postagem original. Quase me faz pensar que não existe um compilador cpp ou algo do tipo, mas g ++ está instalado e o visual studio também não deve ter problemas com c ++.
Chris Covert

Respostas:

185

Também recebi o erro que você mencionou:

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

No meu caso, isso foi devido a ter arquivos C ++ com a .ccextensão.

Se o CMake não for capaz de determinar o idioma do código corretamente, você pode usar o seguinte:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

A resposta aceita que sugere acrescentar o idioma à project()declaração simplesmente adiciona uma verificação mais rigorosa de qual idioma é usado (de acordo com a documentação), mas não foi útil para mim:

Opcionalmente, você pode especificar quais idiomas seu projeto suporta. Linguagens de exemplo são CXX (isto é, C ++), C, Fortran, etc. Por padrão, C e CXX estão habilitados. Por exemplo, se você não tiver um compilador C ++, você pode desabilitar a verificação para ele listando explicitamente os idiomas que deseja oferecer suporte, por exemplo, C. Ao usar a linguagem especial "NENHUMA", todas as verificações de qualquer idioma podem ser desabilitadas. Se existir uma variável chamada CMAKE_PROJECT__INCLUDE_FILE, o arquivo apontado por essa variável será incluído como a última etapa do comando do projeto.

Joakim
fonte
No meu caso, meu arquivo tinha uma extensão .hpp. Isso resolveu!
brawner
O mesmo para mim, arquivo .hpp e isso corrigiu.
KulaGGin de
71

No meu caso, foi apenas porque não havia arquivo de origem no destino. Toda a minha biblioteca era um modelo com código-fonte no cabeçalho. Adicionar um file.cpp vazio resolveu o problema.

Moebius
fonte
6
definir propriedades de destino também funciona para o problema de nenhum arquivo cpp.
Denise Skidmore
1
Parabéns pela dica. Eu também esqueci de mover minhas fontes para o respectivo srcsubdiretório do meu cmakeprojeto recém-criado (uma biblioteca compartilhada) e essa foi basicamente a causa de todo o problema. Nesses casos, você realmente aprecia ter um assistente para cuidar da estrutura do seu cmakeprojeto. : D
rbaleksandar
Mesmo motivo aqui (erro de copiar e colar). Obrigado!
Vivit
2
Dica útil. Mesmo que a sua "biblioteca" seja apenas um cabeçalho, você deve criar um arquivo .cpp que faça um #includepara cada arquivo. Mesmo que não haja saída quando sua biblioteca for compilada, ela fará a verificação da sintaxe do seu arquivo e também verificará as dependências do cabeçalho (por exemplo, cabeçalhos do sistema) que você pode ter perdido.
Mark Lakata
É tão simples quanto isso. O erro de digitação no caminho leva a nenhum arquivo * .cpp nas fontes. Tudo bem depois disso. Obrigado!
Rahul Das
17

Por mais confuso que pareça, o erro também ocorre quando um arquivo cpp incluído no projeto não existe.

Se você listar seus arquivos de origem em CMakeLists.txt e digitar por engano um nome de arquivo, receberá este erro.

Jolly Roger
fonte
Por favor, faça isso como na seção de comentários.
Virb
1
Isso funciona como sua própria resposta, pois é independente do que as outras respostas disseram. Isso também corrigiu meu problema.
Czarking
5

Uma resposta pouco relacionada ao OP, mas para pessoas como eu com um problema semelhante.

Caso de uso: Ubuntu (C, Clion, preenchimento automático):

Eu tive o mesmo erro,

Erro CMake: Não é possível determinar o idioma do link para o "hello" de destino.

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) ajuda a resolver esse problema, mas os cabeçalhos não estão incluídos no projeto e o preenchimento automático não funcionará.

Isso é o que eu tinha

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)

Sem erros, mas não o que eu precisava, percebi que incluir um único arquivo como fonte vai me fazer autocompletar e definir o vinculador para 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
fonte
Reparei que você está usando CXX_FLAGS para definir a versão padrão do C ++ e pensei em mencionar a variável CXX_STANDARD, que acho que é a forma recomendada cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html e deve ser disponível em cmake 3.5
Chris Covert
2

Também enfrentei um erro semelhante ao compilar meu código baseado em C. Corrigi o problema corrigindo o caminho do arquivo de origem no meu cmakearquivo. Verifique o caminho do arquivo de origem de cada arquivo de origem mencionado em seu cmakearquivo. Isso pode ajudar você também.

user2999709
fonte
1

Desejo adicionar outra solução no caso de ser criada uma biblioteca sem nenhum arquivo de origem. Essas bibliotecas também são conhecidas como bibliotecas somente de cabeçalho . Por padrão, add_libraryespera que pelo menos um arquivo de origem seja adicionado ou o erro mencionado ocorrerá. Como as bibliotecas de cabeçalho são bastante comuns, cmake possui a INTERFACEpalavra-chave para construir tais bibliotecas. A INTERFACEpalavra-chave é usada conforme mostrado abaixo e elimina a necessidade de arquivos-fonte vazios adicionados à biblioteca.

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

O exemplo acima construiria uma biblioteca apenas de cabeçalho, incluindo todos os arquivos de cabeçalho no mesmo diretório que CMakeLists.txt. Substitua {CMAKE_CURRENT_SOURCE_DIR}por um caminho caso seus arquivos de cabeçalho estejam em um diretório diferente do arquivo CMakeLists.txt.

Dê uma olhada nesta postagem do blog ou na documentação do cmake para obter mais informações sobre bibliotecas somente de cabeçalho e cmake.

zhm
fonte
0

Por padrão, a pasta JNI Native é nomeada como jni . Renomear para cpp corrigiu o problema

HimalayanCoder
fonte
-2

Consegui resolver o meu, mudando

add_executable(file1.cpp)

para

add_executable(ProjectName file1.cpp)
AKJ
fonte
-2

No meu caso, a implementação de uma função de membro de uma classe em um arquivo de cabeçalho causa esse erro. Separar a interface (no arquivo xh) e a implementação (no arquivo x.cpp) resolve o problema.

Adembudak
fonte