Executing program without an IDE

Pages: 12
Hello,

I have this small project that is consisted by the main.cpp, some other cpp files and their headers. My question is how can a user execute them without opening Xcode for instance? My idea was through the terminal and after a brief research I arrived to the point where I have to write g++ -o output file.cpp but then I get an error saying "clang: error: linker command failed with exit code 1".

Thank you in advance
You have to compile each cpp file and link them with the final executable. Try passing all the cpp files to g++. You might want to also add -Wall to the command line for extra warnings that could be helpful.
It's ok to use the IDE for development. That will create the executable program for you. After that you can close the IDE and just use the generated executable program.
I get an error saying "clang: error: linker command failed with exit code 1".

If you're getting a linker error, you need to resolve that before you will have an executable that will run.

Please post the FULL text of the linker error.
Ok so the full message is like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Undefined symbols for architecture x86_64:
  "elf::elf()", referenced from:
      ss(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int&, int&, int&, int&, int&, int&) in main-fe9624.o
  "elf::~elf()", referenced from:
      ss(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int&, int&, int&, int&, int&, int&) in main-fe9624.o
  "dwarf::dwarf()", referenced from:
      ss(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int&, int&, int&, int&, int&, int&) in main-fe9624.o
  "dwarf::~dwarf()", referenced from:
      ss(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int&, int&, int&, int&, int&, int&) in main-fe9624.o
  "human::human()", referenced from:
      ss(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int&, int&, int&, int&, int&, int&) in main-fe9624.o
  "human::~human()", referenced from:
      ss(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, int&, int&, int&, int&, int&, int&) in main-fe9624.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

To be honest I can't understand what all those things are but I can tell you that the name of the header files are dwarf.hpp, elf.hpp and human.hpp
The whole thing is a small game.

Small edit: what I wrote in the terminal was g++ -o output main.cpp
Last edited on
So do those classes(elf, dwarf, human) have corresponding cpp files? You have to add those on the command line next to main.cpp. Either that or you forgot to implement the constructors and destructors of those classes.

And like Chervil said, the IDE must have created an EXE somewhere that you can run directly, instead of re-compiling on the command line. Also, the IDE should show somewhere the command that it uses to compile. So you can look for that to see how it's done.
Last edited on
It would appear you're doing new and delete on elf, dwarf and human. You apparently have declarations for the constructors and destructors, but either did not implement them, or did not compile them.

@kind9 - As long as the OP has linker errors, an EXE file will not be produced.

Can you please explain what are those "linker errors" and what I should do too fix them? When I build and run the program it runs without any issues.
@kind9 - As long as the OP has linker errors, an EXE file will not be produced.


I thought the OP implied that they had it working in the IDE. I guess it didn't really...
Last edited on
Can you please explain what are those "linker errors"

The linker is saying there are references to the constructors and destructors for elf, dwarf and human, but the linker can't find those functions in the object files you have compiled. You would appear to have declarations for the constructors and destructors, but have not implemented them (or not compiled them).

From your previous post of the error messages:
Line 2: This is a reference to elf's constructor.
Line 4: This is a reference to elf's destructor.
Line 6: This is a reference to dwarf's constructor.
Line 8: This is a reference to dwarf's destructor.
Line 10: This is a reference to human's constructor.
Line 12: This is a reference to human's destructor.
All are references which appear in a function called ss.

i.e.
In your elf.cpp file, do you have a default constructor and destructor for elf?
In your dwarf.cpp file, do you have a default constructor and destructor for dwarf?
In your human.cpp file, do you have a default constructor and destructor for human?

Last edited on
OK I think I have the defaults constructors and destructors. Here is my human.cpp file and below is the human.hpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <fstream>
#include <string>

#include "time.h"
#include "math.h"
#include "stdlib.h"

#include "elf.hpp"
#include "human.hpp"
#include "dwarf.hpp"

using namespace std;



human::human(){
    
    hdex = 15;
    hiq = 16;
    hstrength = 15;
    hhmin = 140;
    hhmax = 210;
}




human::~human(){
    
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef human_hpp
#define human_hpp

#include <stdio.h>
#include <iostream>
using namespace std;



class human{
    
public:
    human();
    
    int hdex;
    int hiq;
    int hstrength;
    
    int hhmin;       
    int hhmax;

    ~human();
    
    
};
#endif 

One last thing, in terminal, what exactly should I type? Thank you for all the help.
Last edited on
I have been trying to tell you that you need to add all of your cpp files, like this:

g++ -o output main.cpp human.cpp elf.cpp dwarf.cpp

I would also add -Wall because it warns you if something in your code is askew:

g++ -Wall -o output main.cpp human.cpp elf.cpp dwarf.cpp

For the record, you don't have to keep compiling them. If those files aren't changing then you can compile them once,

g++ -Wall -c human.cpp elf.cpp dwarf.cpp

and then you can link them with your final executable:

g++ -Wall -o output main.cpp human.o elf.o dwarf.o
Last edited on
OK thank you, now I have the executable file and it works almost fine. I will explain. When a user creates a character, I save his attributes in a file called data.txt so I can read them later. For testing purposes, I have created and deleted many of these data.txt files so I could test the program. When I run the program through Xcode, the output is normal (if there is a file the data are taken correctly and if there isn't, I have to create a new character) but when I try to run it with the executable file that I created, a character is loaded even though I have deleted the file where I store the data. I assume that there is another copy of this data.txt file somewhere. The path for the data.txt that I delete all the time is the following:

/Users/User/Library/Developer/Xcode/DerivedData/(name file)/Build/Products/Debug

Anyone has any ideas?
Thank you for the help

Tiny Update: the data that are presented seem to be quite old. I suspect that they are the data that I inputed the very first time.
Last edited on
Not sure about that one. Can you show the line of code that loads the data.txt file? I guess it depends if you're using a relative path or an absolute path.
kind9 wrote:
I would also add -Wall because it warns you if something in your code is askew:


Yes, but as a bare minimum, I always compile with at least these:

g++ -std=c++14 -Wall -Wextra -pedantic-errors -o OutputFileName *.cpp

Note that compiles all the cpp files in that directory: if you only want some of them then name them individually.

Having more warnings is a good thing, as kind9 says they tell you about potential problems. Perhaps things that will allow the code to compile, but produces a run time error. There is a -Werror option that turns the warnings into errors. This enforces the idea that achieving correct compilation isn't finished until all the warnings are gone.

Doesn't Xcode use clang++ by default ? If it does:

clang++ -std=c++14 -Wall -Wextra -pedantic-errors -o OutputFileName *.cpp

It's worth reading the manual, despite there being zillions of options. There are quite a few handy ones that are not enabled even by -Wall -Wextra -pedantic-errors, I set up my IDE to use these all the time:

clang++ -std=c++14 -Wall -W -Wextra -pedantic-errors -Wuninitialized -Wswitch-default -Wswitch-enum -Wunused -Wfloat-equal -Wconversion -Wzero-as-null-pointer-constant -Weffc++ -o OutputFileName *.cpp

Apparently clang++ has almost the same options as gcc (there might be some specific clang++ ones) , so I have linked part of the manual here:
https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Warning-Options.html#Warning-Options
http://clang.llvm.org/docs/UsersManual.html

Another classic source of problems is the divide by 0 problem. I find it best to explicitly check with code if the denominator is 0 for an int; or near to zero for float or double, that is: less than some precision value that makes sense for the calculation that you are doing. So basically one is trying to identify the problem before it happens rather than try to deal with the consequences after the fact.

When your code does compile and produces an executable, you can run it with ./OutputFileName or whatever ever name you chose with the -o option. The ./ part means that it looks in the current directory for that file: it's a security thing and helps avoid having heaps of directories in a giant path environment variable.

You might also investigate the optimisation options -On where n is the optimisation level. This is how one creates a release version -O3(extra stuff stripped out), as opposed to debug version the default -O0 (all the debug symbols left in, so a debugger has something to work with). The release version will be much smaller.

https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Optimize-Options.html#Optimize-Options

Last edited on
Thank you TheIdeasMan for all these information. I should give it a read.

kind9: I am not sure what you mean by
the line of code that loads the data.txt file?
but here is how I take the data from the data.txt (which is empty the first time):

fname = "data.txt"
1
2
3
4
5
6
ifstream fin(fname);                                    
    
    if(fin.is_open()){
        fin>>name>>race>>level>>strength>>dex>>iq>>height;
        cout<<"Character file retrieved."<<endl;
        }


And at the end of the program all the new values and the different attributes are saved at the same file:
1
2
ofstream fout(fname);                                   
    fout<<endl<<name<<endl<<race<<endl<<level<<endl<<strength<<endl<<dex<<endl<<iq<<endl<<height<<endl;


Of course there is an else statement when taking the data from the file but it is irrelevant and therefore I didn't pasted it.
Are you sure there's no data.txt in the same directory as the EXE?
Last edited on
Yep I am pretty sure. The folder has 9 files: main.cpp human.cpp elf.cpp dwarf.cpp their header files, the executable and a .DS_Store, which is hidden and doesn't really matter.
OK, so I searched for a data.txt and I found the data file in the User/Documents for some reason. Apparently the program was taking this data when executed from the executable file but when it was executed from Xcode the data were stored in the long path I typed previously. Now I have another question: Is there a way to delete a file through the code? I want to make a function called ex.delete so when it is executed the character file will be automatically deleted so the user can create a new character.
OK, some times just googling does the thing. Thank you for your help. Another king of irrelevant question that I have is if you know any good books about benchmarking. Google didn't help me this time.
Pages: 12