Posso chamar um programa .cpp no Bash?

4

Eu sou novo em programação Bash. Eu quero chamar meu programa C ++ no arquivo Bash.

Meu programa é myProg.cpp :

#include<iostream>
using namespace std;
int main()
{
   cout<<"Salam! World"<<endl;
return 0;
}

E meu arquivo bash é myBash.sh . Como posso chamar meu programa .cpp acima no arquivo myBash.sh ?

    
por Prince MUghal 25.03.2015 / 18:52

3 respostas

8

Você precisa compilá-lo primeiro: primeiro altere o diretório de trabalho atual do Terminal para o caminho do seu arquivo de origem:

cd <path_to_cpp_file>/

Em seguida, compile o arquivo de origem:

g++ myProg.cpp -o myProg

Você pode chamar o executável compilado do seu script bash assim:

#!/bin/bash

# ...
<path_to_compiled_executable>/myProg
# ...
    
por kos 25.03.2015 / 19:11
3

Como o seu objetivo real parece ser o de automatizar tudo o que precisa ser feito para executar seu programa, sugiro uma abordagem diferente. Em vez de escrever um script de shell, você pode usar um makefile . Se quiser, você pode escreva uma regra em seu makefile para executar seu executável depois que ele for construído. Você terá então dois arquivos - seu arquivo de código-fonte C ++ e seu makefile - e você poderá executar um único comando com eficiência:

  1. Cria ou recria seu programa C ++, se e somente se necessário .
  2. Executa seu programa.

As seções seguintes desta postagem explicam porque você não pode chamar um arquivo .cpp diretamente (mas deve criar um executável a partir dele primeiro); como instalar o make , como usá-lo e o que ele está fazendo nos bastidores; e como evitar armadilhas comuns. Mas, caso você queira ter uma ideia de como essa abordagem se parece antes de se aprofundar, você executará make run depois de colocar isso 0 em Makefile :

all: myProg

run: all
    ./myProg

Eu gosto disso melhor para este propósito do que um shell script, e eu acho que você também pode.

Antecedentes

Ao contrário de alguns idiomas interpretados como o Python e o Bash, o C ++ é um linguagem compilada . 1 Os programas escritos em C ++ devem ser construído antes de serem executados. (Building também é algumas vezes chamado de compilação , apesar de compilar mais apropriadamente se referir a uma das etapas de construção.) Você não pode executar um C ++ source code ; em vez disso, ele deve ser compilado no código do objeto 2 , neste case linguagem de máquina . Os arquivos de objetos devem ser vinculados e, mesmo que haja apenas um, ele ainda deve estar vinculado a qualquer bibliotecas compartilhadas que ele usa. A vinculação produz um executável que pode ser executado.

Em suma, você tem que construir seu programa antes de executá-lo, pela primeira vez . Antes de execuções subseqüentes, ele não precisa ser re construído, a menos que você tenha alterado o código-fonte. Nesse caso, você deve compilá-lo novamente se quiser que as alterações sejam refletidas no programa executado. O utilitário make foi projetado especificamente para esse tipo de situação, em que se deseja executar ações condicionalmente dependendo se ou não, e quando, eles já foram feitos.

Obtendo make

Você pode já ter o comando make instalado; tente executá-lo para descobrir. Se estiver instalado, você verá algo como:

$ make
make: *** No targets specified and no makefile found.  Stop.

Para conseguir, você pode instalar o make pacote , mas eu sugiro instalar build-essential que fornece várias outras ferramentas úteis. (Você pode ter instalado build-essential para obter g++ , que é uma maneira que você já pode tem make .) Você pode usar o Centro de Software para instalá-lo ou executar o comando:

sudo apt-get update && sudo apt-get install build-essential

make sem um Makefile

Para ver como make funciona, sugiro executá-lo sem um makefile primeiro, passando o nome de base do seu arquivo de código-fonte:

$ make myProg
g++     myProg.cpp   -o myProg
$ ./myProg
Salam! World

Em execuções subseqüentes, make compara os registros de data e hora de modificação ( mtime s) nos arquivos de entrada e saída, e não irá reconstruir seu programa desnecessariamente:

$ make myProg
make: 'myProg' is up to date.

Quando você altera myProg.cpp , isso atualiza seu registro de data e hora de modificação, portanto, make saberá recriá-lo. (Você também pode atualizar o registro de data e hora de um arquivo com o comando touch , se você precisa ou quer forçar qualquer arquivo de saída dependendo dele para ser reconstruído E, claro, a exclusão dos arquivos de saída também garantirá que eles sejam reconstruídos quando você executar make - apenas não exclua o arquivo errado!)

$ touch myProg.cpp
$ make myProg
g++     myProg.cpp   -o myProg

Como o make sabe o que fazer quando você executa make myProg ?

  • O argumento myProg para make é chamado de destino .
  • Os destinos geralmente são, mas nem sempre, os nomes dos arquivos a serem criados. Os alvos podem ser definidos explicitamente em um makefile.
  • Quando um alvo não é definido no makefile ou (como neste caso) não há makefile, make procura por arquivos de entrada (ou seja, código-fonte) nomeados de forma a sugerir que eles são destinados à construção o alvo.
  • make infere qual utilitário e sintaxe usar na construção de um arquivo a partir de seu sufixo (neste caso, .cpp ).

Tudo isso pode ser personalizado, mas em casos simples como este, muitas vezes não precisa ser.

Criando um Makefile para automatizar a criação e a execução do seu programa

Para automatizar tarefas mais complexas do que criar um programa a partir de um único arquivo de código-fonte, como se houvesse vários arquivos de entrada ou (mais aplicável a suas necessidades imediatas) ações que você deseja executar além do compilador, crie um makefile para definir metas para make e especificar como elas dependem de outros destinos.

O primeiro alvo definido em um makefile é o destino padrão: é o que make tenta construir quando executado sem argumentos de linha de comando (ou seja, quando você executa apenas make e não algo como make myProg ).

A maneira usual de usar makefiles é criar um diretório contendo todos os arquivos de código-fonte (e quaisquer outros arquivos) usados para construir seu programa, bem como o makefile, que geralmente é chamado de Makefile . Com esse nome, make irá encontrá-lo automaticamente.

Para criar um makefile você pode usar para executar myProg e isso irá construí-lo automaticamente quando necessário, coloque myProg.cpp no diretório novo, caso contrário, vazio. Crie outro arquivo de texto nesse diretório chamado Makefile .

Você pode usar qualquer editor de texto para isso, mas a receita de uma regra - os comandos listados abaixo que serão executados para criar o destino - deve ser recuada com guias em vez de espaços . 3 Então, se o seu editor de texto está atualmente configurado para recuar com espaços quando você pressiona Tab , você deve mudar isso.

Por exemplo, em Gedit ou Pluma, você entra em Editar & gt; Preferências , clique na guia Editor e certifique-se de que Inserir espaços em vez de guias esteja desmarcado:

Muitos editores adotam o padrão de recuar nas guias e não nos espaços, portanto, se você não alterou essa configuração antes, ela já pode estar definida corretamente para os makefiles.

Quando você estiver no seu editor e (se necessário) configurado para recuar com guias, coloque isso em:

all: myProg

run: all
    ./myProg

Se você copiar e colar isto, estará errado porque os espaços serão copiados mesmo que o seu editor de texto não os faça quando você pressionar Tab . (Isso tem a ver com a maneira como o Ask exibe código do Ubuntu.) Mas você pode simplesmente remover os quatro espaços anteriores a ./myProg e pressionar a tecla Tab para criar uma tabulação em seu lugar.

Alguns editores de texto têm como padrão mostrar uma guia como 8 espaços ou algum outro número. Tudo bem.

O que esse Makefile faz e como usá-lo

Use o comando:

  • make , para construir o programa, a menos que já esteja compilado e o executável esteja atualizado com o código-fonte. Ou
  • make run , para executar o programa, construindo primeiro se necessário (ou seja, se não houver nenhum executável atual).

Este makefile define dois alvos: all e run .

  • A meta all não tem receita própria, mas depende da meta myProg . Esse destino não é explicitamente definido, portanto, ele diz implicitamente que make tenta criar myProg de qualquer arquivo de código-fonte disponível no diretório atual. (Veja a seção make sem um Makefile acima para detalhes.)

    Como all é o primeiro destino explicitamente definido em Makefile , ele será criado quando make for executado no diretório em que Makefile reside. Assim, configuramos as coisas, então executar make por si só equivale a executar make all .

  • O run target executa o programa. Sua receita consiste no comando que faz isso, ./myProg . run declara a all alvo como uma dependência. Isso faz com que, quando você executar make run , myProg seja recriado se o executável myProg atual não for atual (ou ainda não existir).

    Poderíamos também fazer com que run dependesse de myProg em vez de all , mas ainda assim teríamos necessário o all target explícito (ou uma meta equivalente de um nome diferente) para evitar run de ser o alvo padrão. Claro, se você quer que o seu programa construa e execute mesmo quando você executa make , você pode fazer isso.

    Outro benefício de depender da meta all é no caso de ocorrerem mais ações que devem ser tomadas antes que seu programa seja executado. Você pode adicionar uma receita à regra para all .

Usar o makefile para executar o programa se parece com isso, se precisar ser criado:

$ cd myProg/
$ make run
g++     myProg.cpp   -o myProg
./myProg
Salam! World

Ou isso, se não precisar ser criado:

$ make run
./myProg
Salam! World

E se você quiser apenas ter certeza de que o programa foi criado (desde que o arquivo de código-fonte foi modificado pela última vez) sem executar o programa , simplesmente execute make sem argumentos:

$ make      # Here, I run make and myProg isn't current.
g++     myProg.cpp   -o myProg
$ make      # Running "make" again after "make" or "make run" does nothing.
make: Nothing to be done for 'all'.

( make myProg ainda funcionará também.)

Um refinamento: sinalizadores personalizados do compilador

make é uma ferramenta extremamente poderosa, útil para propósitos simples como este, mas também adequada para projetos grandes e complexos. A tentativa de detalhar tudo o que você pode fazer com make seria um livro inteiro (especificamente, este ).

Mas me ocorreu que você pode querer ver avisos do compilador, quando algo não impede a conclusão da construção, mas ainda é um erro potencial. Estes não vão pegar todos os bugs nos programas que você escreve, mas eles podem pegar muitos.

Ao usar o GCC (como acontece com o comando g++ ), recomendo passar pelo menos -Wall para o compilador. Isso realmente não habilita todos avisos, mas você pode habilitar a maior parte do restante com -Wextra . Às vezes, você também pode querer -pedantic . (Veja man gcc e 3.8 Opções para solicitar ou suprimir avisos no Manual de referência do GCG .)

Para invocar g++ manualmente com esses sinalizadores, você executaria:

g++ -Wall -Wextra -pedantic -o myProg myProg.cpp

Para fazer com que make invoque o compilador C ++ ( g++ ) com os sinalizadores -Wall , -Wextra e -pedantic , adicione uma linha CXXFLAGS= com eles ao início de Makefile .

CXXFLAGS=-Wall -Wextra -pedantic

all: myProg

run: all
    ./myProg

Mesmo que myProg exista e seja mais recente que myProg.cpp , a execução de make ou make run após a edição de Makefile continuará criando o programa novamente, porque Makefile é agora mais recente que myProg . Isso é bom, porque:

  • Nesse caso, a reconstrução do executável faz com que você veja avisos se houver algum (não deveria haver, para esse programa específico).
  • Mais geralmente, às vezes, quando você edita um makefile, é porque deseja que diferentes arquivos sejam produzidos ou que sejam produzidos com diferentes conteúdos. (Por exemplo, se você tivesse adicionado o sinal -O3 para otimizações pesadas ou -g para fazer o compilador gerar símbolos de depuração, o executável myProg resultante seria diferente.)

Leitura Adicional

Notas

0 : recomendo ler mais para ver como fazer isso funcionar. Mas no caso de você querer tentar primeiro você mesmo: você deve recuar linhas com abas em vez de espaços.

1 : Estritamente falando, virtualmente qualquer linguagem de programação pode ser interpretada ou compilada dependendo do que implementações para isso foram escritas. Para alguns idiomas, ambos os interpretadores e compiladores existem. Entretanto, o C ++ interpretado é incomum - embora não seja conhecido .

2 : dividindo o edifício em compilando e ligando , e chamando a tradução de um arquivo de código-fonte C ++ (.cc / .cpp / .cxx / .C) no código de objeto compilação , não é toda a história. Programas em C e C ++ (e algumas outras linguagens) são os primeiros pré-processados . Em seu programa, o pré-processador C substitui #include<iostream> pelo conteúdo do arquivo de cabeçalho <iostream> antes do início da compilação real. E, no sentido mais restrito, a compilação converte o código-fonte em linguagem assembly em vez de código-objeto.Muitos compiladores (como o GCC / g++ ) podem combinar compilação e montagem em uma única etapa e não produzem código assembly a menos que sejam solicitados a fazê-lo.

Enquanto o pré-processamento é uma etapa separada, o GCC e outros compiladores executam automaticamente o pré-processador. Da mesma forma, eles podem executar automaticamente o vinculador, e é por isso que toda a seqüência de pré-processamento , compilação , montagem e ligação é às vezes chamado de "compilação" em vez de "construção". (Observe também que o edifício pode conter mais do que essas etapas - por exemplo, pode envolver a geração de arquivos de recursos, executando um script para configurar como as coisas será construído , etc.)

3 : Você só precisa recuar com guias no makefile propriamente dito. Usar um makefile não impõe nenhum requisito ao modo como você escreve seus próprios arquivos de código-fonte C ++. Sinta-se à vontade para mudar o recuo de abas para espaços quando estiver trabalhando em outros arquivos. (E se você realmente não gostar de recuar com guias em um makefile, você pode definir o .RECIPEPREFIX variável especial .

    
por Eliah Kagan 18.04.2015 / 00:52
0

Veja um exemplo: em myBash.sh

#!/bin/sh
g++ myProg.cpp -o myProg
./myProg
    
por Tohid Tamboli 25.03.2015 / 20:02