C++, the “Old Fashioned” way

前端 未结 8 1027
孤街浪徒
孤街浪徒 2021-02-04 14:56

I have been learning C++ in school to create small command-line programs.

However, I have only built my projects with IDEs, including VS08 and QtCreator.

I under

相关标签:
8条回答
  • 2021-02-04 15:41

    I like this quirky intro to building a hello world program with gcc, Linux-based but the command-line stuff should work fine on OS/X. In particular, it walks you through making some common mistakes and seeing the error messages.

    Holy Compilers, Robin, the darn thing worked!

    0 讨论(0)
  • 2021-02-04 15:43

    This is what has helped me to learn the autoconf, automake, ...:

    http://www.bioinf.uni-freiburg.de/~mmann/HowTo/automake.html

    It is a nice tutorial progresses from a simple helloworld to more advanced structures with libraries etc.

    0 讨论(0)
  • 2021-02-04 15:44

    Just to throw this out there, the complete gcc documentation can be found here: http://www.delorie.com/gnu/docs/gcc/gcc_toc.html

    0 讨论(0)
  • 2021-02-04 15:45

    compiler takes a cpp and turns into an object file which contains native code and some information about that native code

    a linker takes the object files and lays out an excutable using the extra information in the object file.... it finds all the references to the same things and links them up, and makes and image useful for the operating system to know how to load all the code into memory.

    check out object file formats to get a better understanding of what the compiler produces

    http://en.wikipedia.org/wiki/Object_file (different compilers use different formats)

    also check out (for gcc)

    http://pages.cs.wisc.edu/~beechung/ref/gcc-intro.html on what you type at the command line

    0 讨论(0)
  • 2021-02-04 15:46

    A simple example is often useful to show the basic procedure, so:

    Sample gcc usage to compile C++ files:

    $ g++ -c file1.cpp                 # compile object files
    [...]
    $ g++ -c file2.cpp
    [...]
    $ g++ -o program file1.o file2.o   # link program
    [...]
    $ ./program                        # run program
    

    To use make to do this build, the following Makefile could be used:

    # main target, with dependencies, followed by build command (indented with <tab>)
    program: file1.o file2.o
        g++ -o program file1.o file2.o
    
    # rules for object files, with dependencies and build commands
    file1.o: file1.cpp file1.h
        g++ -c file1.cpp
    
    file2.o: file2.cpp file2.h file1.h
        g++ -c file2.cpp
    

    Sample Makefile usage:

    $ make                              # build it
    [...]
    $ ./program                         # run it
    

    For all the details you can look at the Gnu make manual and GCC's documentation.

    0 讨论(0)
  • 2021-02-04 15:49

    Compiling

    Let's say you want to write a simple 'hello world' application. You have 3 files, hello.cpp hello-writer.cpp and hello-writer.h, the contents being

    // hello-writer.h
    void WriteHello(void);
    
    // hello-writer.cpp
    #include "hello-writer.h"
    #include <stdio>
    void WriteHello(void){
        std::cout<<"Hello World"<<std::endl;
    }
    
    // hello.cpp
    #include "hello-writer.h"
    int main(int argc, char ** argv){
        WriteHello();
    }
    

    The *.cpp files are converted to object files by g++, using the commands

    g++ -c hello.cpp -o hello.o
    g++ -c hello-writer.cpp -o hello-writer.o
    

    The -c flag skips the linking for the moment. To link all the modules together requires running

    g++ hello.o hello-writer.o -o hello
    

    creating the program hello. If you need to link in any external libraries you add them to this line, eg -lm for the math library. The actual library files would look something like libm.a or libm.so, you ignore the suffix and the 'lib' part of the filename when adding the linker flag.

    Makefile

    To automate the build process you use a makefile, which consists of a series of rules, listing a thing to create and the files needed to create it. For instance, hello.o depends on hello.cpp and hello-writer.h, its rule is

    hello.o:hello.cpp hello-writer.h
         g++ -c hello.cpp -o hello.o # This line must begin with a tab.
    

    If you want to read the make manual, it tells you how to use variables and automatic rules to simplify things. You should be able to just write

    hello.o:hello.cpp hello-writer.h
    

    and the rule will be created automagically. The full makefile for the hello example is

    all:hello
    hello:hello.o hello-writer.o
        g++ hello.o hello-writer.o -o hello
    hello.o:hello.cpp hello-writer.h
        g++ -c hello.cpp -o hello.o
    hello-writer.o:hello-writer.cpp hello-writer.h
        g++ -c hello-writer.cpp -o hello-writer.o
    

    Remember that indented lines must start with tabs. Not that not all rules need an actual file, the all target just says create hello. It is common for this to be the first rule in the makefile, the first being automatically created when you run make.

    With all this set up you should then be able to go to a command line and run

    $ make
    $ ./hello
    Hello World
    

    More advanced Makefile stuff

    There are also some useful variables that you can define in your makefile, which include

    • CXX: c++ compiler
    • CXXFLAGS: Additional flags to pass to the compiler (E.g include directories with -I)
    • LDFLAGS: Additional flags to pass to the linker
    • LDLIBS: Libraries to link
    • CC: c compiler (also used to link)
    • CPPFLAGS: preprocessor flags

    Define variables using =, add to variables using +=.

    The default rule to convert a .cpp file to a .o file is

    $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@
    

    where $< is the first dependancy and $@ is the output file. Variables are expanded by enclosing them in $(), this rule will be run with the pattern hello.o:hello.cpp

    Similarly the default linker rule is

    $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)
    

    where $^ is all of the prerequisites. This rule will be run with the pattern hello:hello.o hello-writer.o. Note that this uses the c compiler, if you don't want to override this rule and are using c++ add the library -lstdc++ to LDLIBS with the line

    LDLIBS+=-lstdc++
    

    in the makefile.

    Finally, if you don't list the dependancies of a .o file make can find them itself, so a minimal makefile might be

    LDFLAGS=-lstdc++
    all:hello
    hello:hello.o hello-writer.o
    

    Note that this ignores the dependancy of the two files on hello-writer.h, so if the header is modified the program won't be rebuilt. If you're interested, check the -MD flag in the gcc docs for how you can automatically generate this dependancy.

    Final makefile

    A reasonable final makefile would be

    // Makefile
    CC=gcc
    CXX=g++
    CXXFLAGS+=-Wall -Wextra -Werror
    CXXFLAGS+=-Ipath/to/headers
    LDLIBS+=-lstdc++ # You could instead use CC = $(CXX) for the same effect 
                     # (watch out for c code though!)
    
    all:hello                                   # default target
    hello:hello.o hello-world.o                 # linker
    hello.o:hello.cpp hello-world.h             # compile a module
    hello-world.o:hello-world.cpp hello-world.h # compile another module
        $(CXX) $(CXXFLAGS) -c $< -o $@          # command to run (same as the default rule)
                                                # expands to g++ -Wall ... -c hello-world.cpp -o hello-world.o
    
    0 讨论(0)
提交回复
热议问题