Compiling C/C++ code by way of including preprocessor build instructions in an actual C/C++ source file

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












0















I've got reasons for not wanting to rely on a specific build system. I don't mean to dis anybody's favorite, but I really just want to stick to what comes with the compiler. In this case, GCC. Automake has certain compatibility issues, especially with Windows. <3 GNU make is so limited that it often needs to be supplemented with shell scripts. Shell scripts can take many forms, and to make a long story short and probably piss a lot of people off, here is what I want to do --



The main entry point is God. Be it a C or C++ source file, it is the center of the application. Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled. Let me explain --



There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over. Any library that needs to be dynamically linked can be included as a supporting file of the application. For that reason, separate build instructions for .SOs (and maybe .DLLs ;]) is all fine and dandy, because they are separate executable files. Any other library should be statically linked. Now, let's talk about static linking --



Static linking is a real bitch. That's what makefiles are for. If the whole project was written in one language (for instance C OR C++), you can #include the libraries as headers. That's just fine. But now, let's consider another scenario --



Let's say you're like me and can't be arsed to figure out C's difficult excuse for strings, so you decide to use C++. But you want to use a C library, like for instance MiniBasic. God help us. If the C library wasn't designed to conform to C++'s syntax, you're screwed. That's when makefiles come in, since you need to compile the C source file with a C compiler and the C++ source file with a C++ compiler. I don't want to use makefiles.



I would hope that there is a way to exploit GCC's preprocessor macros to tell it something like this:




Hi, GCC. How are you doing? In case you forgot, this source file you're looking at right now is written in C++. You should of course compile it with G++. There's another file that this file needs, but it's written in C. It's called "lolcats.c". I want you to compile that one with GCC into an object file and I want you to compile this one with G++ into the main object file, then I want you to link them together into an executable file.




How might I write such a thing in preprocessor lingo? Does GCC even do that?










share|improve this question
























  • You could decide that all your things are plugins.

    – Basile Starynkevitch
    Jul 20 '14 at 11:29






  • 3





    Your question is unclear.

    – Basile Starynkevitch
    Jul 20 '14 at 11:39















0















I've got reasons for not wanting to rely on a specific build system. I don't mean to dis anybody's favorite, but I really just want to stick to what comes with the compiler. In this case, GCC. Automake has certain compatibility issues, especially with Windows. <3 GNU make is so limited that it often needs to be supplemented with shell scripts. Shell scripts can take many forms, and to make a long story short and probably piss a lot of people off, here is what I want to do --



The main entry point is God. Be it a C or C++ source file, it is the center of the application. Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled. Let me explain --



There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over. Any library that needs to be dynamically linked can be included as a supporting file of the application. For that reason, separate build instructions for .SOs (and maybe .DLLs ;]) is all fine and dandy, because they are separate executable files. Any other library should be statically linked. Now, let's talk about static linking --



Static linking is a real bitch. That's what makefiles are for. If the whole project was written in one language (for instance C OR C++), you can #include the libraries as headers. That's just fine. But now, let's consider another scenario --



Let's say you're like me and can't be arsed to figure out C's difficult excuse for strings, so you decide to use C++. But you want to use a C library, like for instance MiniBasic. God help us. If the C library wasn't designed to conform to C++'s syntax, you're screwed. That's when makefiles come in, since you need to compile the C source file with a C compiler and the C++ source file with a C++ compiler. I don't want to use makefiles.



I would hope that there is a way to exploit GCC's preprocessor macros to tell it something like this:




Hi, GCC. How are you doing? In case you forgot, this source file you're looking at right now is written in C++. You should of course compile it with G++. There's another file that this file needs, but it's written in C. It's called "lolcats.c". I want you to compile that one with GCC into an object file and I want you to compile this one with G++ into the main object file, then I want you to link them together into an executable file.




How might I write such a thing in preprocessor lingo? Does GCC even do that?










share|improve this question
























  • You could decide that all your things are plugins.

    – Basile Starynkevitch
    Jul 20 '14 at 11:29






  • 3





    Your question is unclear.

    – Basile Starynkevitch
    Jul 20 '14 at 11:39













0












0








0








I've got reasons for not wanting to rely on a specific build system. I don't mean to dis anybody's favorite, but I really just want to stick to what comes with the compiler. In this case, GCC. Automake has certain compatibility issues, especially with Windows. <3 GNU make is so limited that it often needs to be supplemented with shell scripts. Shell scripts can take many forms, and to make a long story short and probably piss a lot of people off, here is what I want to do --



The main entry point is God. Be it a C or C++ source file, it is the center of the application. Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled. Let me explain --



There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over. Any library that needs to be dynamically linked can be included as a supporting file of the application. For that reason, separate build instructions for .SOs (and maybe .DLLs ;]) is all fine and dandy, because they are separate executable files. Any other library should be statically linked. Now, let's talk about static linking --



Static linking is a real bitch. That's what makefiles are for. If the whole project was written in one language (for instance C OR C++), you can #include the libraries as headers. That's just fine. But now, let's consider another scenario --



Let's say you're like me and can't be arsed to figure out C's difficult excuse for strings, so you decide to use C++. But you want to use a C library, like for instance MiniBasic. God help us. If the C library wasn't designed to conform to C++'s syntax, you're screwed. That's when makefiles come in, since you need to compile the C source file with a C compiler and the C++ source file with a C++ compiler. I don't want to use makefiles.



I would hope that there is a way to exploit GCC's preprocessor macros to tell it something like this:




Hi, GCC. How are you doing? In case you forgot, this source file you're looking at right now is written in C++. You should of course compile it with G++. There's another file that this file needs, but it's written in C. It's called "lolcats.c". I want you to compile that one with GCC into an object file and I want you to compile this one with G++ into the main object file, then I want you to link them together into an executable file.




How might I write such a thing in preprocessor lingo? Does GCC even do that?










share|improve this question
















I've got reasons for not wanting to rely on a specific build system. I don't mean to dis anybody's favorite, but I really just want to stick to what comes with the compiler. In this case, GCC. Automake has certain compatibility issues, especially with Windows. <3 GNU make is so limited that it often needs to be supplemented with shell scripts. Shell scripts can take many forms, and to make a long story short and probably piss a lot of people off, here is what I want to do --



The main entry point is God. Be it a C or C++ source file, it is the center of the application. Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled. Let me explain --



There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over. Any library that needs to be dynamically linked can be included as a supporting file of the application. For that reason, separate build instructions for .SOs (and maybe .DLLs ;]) is all fine and dandy, because they are separate executable files. Any other library should be statically linked. Now, let's talk about static linking --



Static linking is a real bitch. That's what makefiles are for. If the whole project was written in one language (for instance C OR C++), you can #include the libraries as headers. That's just fine. But now, let's consider another scenario --



Let's say you're like me and can't be arsed to figure out C's difficult excuse for strings, so you decide to use C++. But you want to use a C library, like for instance MiniBasic. God help us. If the C library wasn't designed to conform to C++'s syntax, you're screwed. That's when makefiles come in, since you need to compile the C source file with a C compiler and the C++ source file with a C++ compiler. I don't want to use makefiles.



I would hope that there is a way to exploit GCC's preprocessor macros to tell it something like this:




Hi, GCC. How are you doing? In case you forgot, this source file you're looking at right now is written in C++. You should of course compile it with G++. There's another file that this file needs, but it's written in C. It's called "lolcats.c". I want you to compile that one with GCC into an object file and I want you to compile this one with G++ into the main object file, then I want you to link them together into an executable file.




How might I write such a thing in preprocessor lingo? Does GCC even do that?







gcc c++ programming linker static-linking






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 13 at 22:19









Rui F Ribeiro

39.7k1479132




39.7k1479132










asked Jul 20 '14 at 2:03









user78076user78076

124




124












  • You could decide that all your things are plugins.

    – Basile Starynkevitch
    Jul 20 '14 at 11:29






  • 3





    Your question is unclear.

    – Basile Starynkevitch
    Jul 20 '14 at 11:39

















  • You could decide that all your things are plugins.

    – Basile Starynkevitch
    Jul 20 '14 at 11:29






  • 3





    Your question is unclear.

    – Basile Starynkevitch
    Jul 20 '14 at 11:39
















You could decide that all your things are plugins.

– Basile Starynkevitch
Jul 20 '14 at 11:29





You could decide that all your things are plugins.

– Basile Starynkevitch
Jul 20 '14 at 11:29




3




3





Your question is unclear.

– Basile Starynkevitch
Jul 20 '14 at 11:39





Your question is unclear.

– Basile Starynkevitch
Jul 20 '14 at 11:39










4 Answers
4






active

oldest

votes


















6















The main entry point is God. Be it a C or C++ source file, it is the center of the application.




Only in the same way that nitrogen is the center of a pine tree. It is where everything starts, but there's nothing about C or C++ that makes you put the "center" of your application in main().



A great many C and C++ programs are built on an event loop or an I/O pump. These are the "centers" of such programs. You don't even have to put these loops in the same module as main().




Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled.




It is actually easiest to put main() last in a C or C++ source file.



C and C++ are not like some languages, where symbols can be used before they are declared. Putting main() first means you have to forward-declare everything else.




There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over.




"Tell 'im 'e's dreamin'!"



OS X and iOS are full of proprietary code, and Microsoft isn't going away any time soon.



What do Microsoft's current difficulties have to do with your question, anyway? You say you might want to make DLLs, and you mention Automake's inability to cope effectively with Windows. That tells me Microsoft remains relevant in your world, too.




Static linking is a real bitch.




Really? I've always found it easier than linking to dynamic libraries. It's an older, simpler technology, with fewer things to go wrong.



Static linking incorporates the external dependencies into the executable, so that the executable stands alone, self-contained. From the rest of your question, that should appeal to you.




you can #include the libraries as headers




No... You #include library headers, not libraries.



This isn't just pedantry. The terminology matters. It has meaning.



If you could #include libraries, #include </usr/lib/libfoo.a> would work.



In many programming languages, that is the way external module/library references work. That is, you reference the external code directly.



C and C++ are not among the languages that work that way.




If the C library wasn't designed to conform to C++'s syntax, you're screwed.




No, you just have to learn to use C++. Specifically here, extern "C".




How might I write such a thing in preprocessor lingo?




It is perfectly legal to #include another C or C++ file:



#include <some/library/main.cpp>

#include <some/other/library/main.c>
#include <some/other/library/secondary_module.c>

#include <iostream>

int main()

call_the_library();
do_other_stuff();
return 0;



We don't use extern "C" here because this pulls the C and C++ code from those other libraries directly into our C++ file, so the C modules need to be legal C++ as well. There are a number of annoying little differences between C and C++, but if you're going to intermix the two languages, you're going to have to know how to cope with them regardless.



Another tricky part of doing this is that the order of the #includes is more sensitive than the order of library references if a linker command. When you bypass the linker in this way, you end up having to do some things manually that the linker would otherwise do for you automatically.



To prove the point, I took MiniBasic (your own example) and converted its script.c driver program to a standalone C++ program that says #include <basic.c> instead of #include <basic.h>. (patch) Just to prove that it's really a C++ program now, I changed all the printf() calls to cout stream insertions.



I had to make a few other changes, all of them well within a normal day's work for someone who's going to intermix C and C++:



  1. The MiniBasic code makes use of C's willingness to tolerate automatic conversions from void* to any other pointer type. C++ makes you be explicit.


  2. Newer compilers are no longer tolerating use of C string constants (e.g. "Hello, world!n") in char* contexts. The standard says the compiler is allowed to place them into read-only memory, so you need to use const char*.


That's it. Just a few minutes work, patching GCC complaints.



I had to make some similar changes in basic.c to those in the linked script.c patch file. I haven't bothered posting the diffs, since they're just more of the same.



For another way to go about this, study the SQLite Amalgamation, as compared to the SQLite source tree. SQLite doesn't use #include all the other files into a single master file; they're actually concatenated together, but that is also all #include does in C or C++.






share|improve this answer
































    1














    gcc will compile C and C and C++ as C++ simply as a result of you naming the files appropriately, the preprocessor doesn't come into that. You'll need extern "C" blocks around your C declarations in your C++ files to make sure the linker can link stuff correctly, though.



    But what you're describing is almost never going to be helpful. If you're using a library that needs some kind of configuration to compile in the first place, then it's still going to need it if you just try to compile the files directly into your project. Not many real-world non-trivial libraries are pure ISO C that will compile on every platform without modification or some kind of configure script, so you'd be creating complexity most of the time, not reducing it, because you're going to have to deal with that configuration in your own build somehow.






    share|improve this answer






























      1














      No, you can't do that. There's no gcc pragma for compile in this way.
      The most similar is the Microsoft Visual C++ #pragma comment(lib, …) or #pragma comment(linker, …) [1] [2] for noting that some libraries should be included in the link procedure.




      Hi, GCC. How are you doing? In case you forgot, this source file
      you're looking at right now is written in C++. You should of course
      compile it with G++. There's another file that this file needs, but
      it's written in C. It's called "lolcats.c". I want you to compile that
      one with GCC into an object file and I want you to compile this one
      with G++ into the main object file, then I want you to link them
      together into an executable file.




      Your request is exactly what a Makefile does.



      You could create a shell script that extracts the source files and compiles them with whatever command you want to use. But it's The Wrong Solution™



      If you have multiple files, store them as multiple files. If you want people not to use make or cmake, don't provide a Makefile/CMakefile. Give them for instance a compile-me.sh file.



      The only case when I feel I am in a similar situation is whan I code a util in a single file, but I simply provide the compilation command at the top inside a comment.






      share|improve this answer






























        0














        You could decide that all your things are plugins. Then compile them with gcc -shared -fPIC -O thing1.cc -o thing1.so and have a main stub program doing dlopen(3) on ./thing1.so then dlsym on God; on Linux you could have binfmt_misc tricks to make that more transparent.



        If you insist on having self-containing programs, notice that GCC has the -ffreestanding option. It is then up to you to provide a runtime environment (at the very least, for some basic I/O thru system calls which you would need to interface, see syscalls(2)). Study carefully the relevant ABI spec. For Linux/x86-64 it is here. Read about calling conventions.



        You could also customize GCC with compiler plugins like MELT (then you could add a #pragma which would do arbitrary things, perhaps even forking a gcc...)



        BTW, an entry point like your God is not a source file, but some label known to the linker.



        Reading more about compilers, linkers (see Levine's book: Linkers and Loaders, object files, ELF, libraries and shared objects (see Drepper's paper: How to Write Shared Libraries ...), crt0.o should help.



        See also the C++ module draft proposal N3347






        share|improve this answer
























          Your Answer








          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "106"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f145527%2fcompiling-c-c-code-by-way-of-including-preprocessor-build-instructions-in-an-a%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          6















          The main entry point is God. Be it a C or C++ source file, it is the center of the application.




          Only in the same way that nitrogen is the center of a pine tree. It is where everything starts, but there's nothing about C or C++ that makes you put the "center" of your application in main().



          A great many C and C++ programs are built on an event loop or an I/O pump. These are the "centers" of such programs. You don't even have to put these loops in the same module as main().




          Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled.




          It is actually easiest to put main() last in a C or C++ source file.



          C and C++ are not like some languages, where symbols can be used before they are declared. Putting main() first means you have to forward-declare everything else.




          There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over.




          "Tell 'im 'e's dreamin'!"



          OS X and iOS are full of proprietary code, and Microsoft isn't going away any time soon.



          What do Microsoft's current difficulties have to do with your question, anyway? You say you might want to make DLLs, and you mention Automake's inability to cope effectively with Windows. That tells me Microsoft remains relevant in your world, too.




          Static linking is a real bitch.




          Really? I've always found it easier than linking to dynamic libraries. It's an older, simpler technology, with fewer things to go wrong.



          Static linking incorporates the external dependencies into the executable, so that the executable stands alone, self-contained. From the rest of your question, that should appeal to you.




          you can #include the libraries as headers




          No... You #include library headers, not libraries.



          This isn't just pedantry. The terminology matters. It has meaning.



          If you could #include libraries, #include </usr/lib/libfoo.a> would work.



          In many programming languages, that is the way external module/library references work. That is, you reference the external code directly.



          C and C++ are not among the languages that work that way.




          If the C library wasn't designed to conform to C++'s syntax, you're screwed.




          No, you just have to learn to use C++. Specifically here, extern "C".




          How might I write such a thing in preprocessor lingo?




          It is perfectly legal to #include another C or C++ file:



          #include <some/library/main.cpp>

          #include <some/other/library/main.c>
          #include <some/other/library/secondary_module.c>

          #include <iostream>

          int main()

          call_the_library();
          do_other_stuff();
          return 0;



          We don't use extern "C" here because this pulls the C and C++ code from those other libraries directly into our C++ file, so the C modules need to be legal C++ as well. There are a number of annoying little differences between C and C++, but if you're going to intermix the two languages, you're going to have to know how to cope with them regardless.



          Another tricky part of doing this is that the order of the #includes is more sensitive than the order of library references if a linker command. When you bypass the linker in this way, you end up having to do some things manually that the linker would otherwise do for you automatically.



          To prove the point, I took MiniBasic (your own example) and converted its script.c driver program to a standalone C++ program that says #include <basic.c> instead of #include <basic.h>. (patch) Just to prove that it's really a C++ program now, I changed all the printf() calls to cout stream insertions.



          I had to make a few other changes, all of them well within a normal day's work for someone who's going to intermix C and C++:



          1. The MiniBasic code makes use of C's willingness to tolerate automatic conversions from void* to any other pointer type. C++ makes you be explicit.


          2. Newer compilers are no longer tolerating use of C string constants (e.g. "Hello, world!n") in char* contexts. The standard says the compiler is allowed to place them into read-only memory, so you need to use const char*.


          That's it. Just a few minutes work, patching GCC complaints.



          I had to make some similar changes in basic.c to those in the linked script.c patch file. I haven't bothered posting the diffs, since they're just more of the same.



          For another way to go about this, study the SQLite Amalgamation, as compared to the SQLite source tree. SQLite doesn't use #include all the other files into a single master file; they're actually concatenated together, but that is also all #include does in C or C++.






          share|improve this answer





























            6















            The main entry point is God. Be it a C or C++ source file, it is the center of the application.




            Only in the same way that nitrogen is the center of a pine tree. It is where everything starts, but there's nothing about C or C++ that makes you put the "center" of your application in main().



            A great many C and C++ programs are built on an event loop or an I/O pump. These are the "centers" of such programs. You don't even have to put these loops in the same module as main().




            Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled.




            It is actually easiest to put main() last in a C or C++ source file.



            C and C++ are not like some languages, where symbols can be used before they are declared. Putting main() first means you have to forward-declare everything else.




            There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over.




            "Tell 'im 'e's dreamin'!"



            OS X and iOS are full of proprietary code, and Microsoft isn't going away any time soon.



            What do Microsoft's current difficulties have to do with your question, anyway? You say you might want to make DLLs, and you mention Automake's inability to cope effectively with Windows. That tells me Microsoft remains relevant in your world, too.




            Static linking is a real bitch.




            Really? I've always found it easier than linking to dynamic libraries. It's an older, simpler technology, with fewer things to go wrong.



            Static linking incorporates the external dependencies into the executable, so that the executable stands alone, self-contained. From the rest of your question, that should appeal to you.




            you can #include the libraries as headers




            No... You #include library headers, not libraries.



            This isn't just pedantry. The terminology matters. It has meaning.



            If you could #include libraries, #include </usr/lib/libfoo.a> would work.



            In many programming languages, that is the way external module/library references work. That is, you reference the external code directly.



            C and C++ are not among the languages that work that way.




            If the C library wasn't designed to conform to C++'s syntax, you're screwed.




            No, you just have to learn to use C++. Specifically here, extern "C".




            How might I write such a thing in preprocessor lingo?




            It is perfectly legal to #include another C or C++ file:



            #include <some/library/main.cpp>

            #include <some/other/library/main.c>
            #include <some/other/library/secondary_module.c>

            #include <iostream>

            int main()

            call_the_library();
            do_other_stuff();
            return 0;



            We don't use extern "C" here because this pulls the C and C++ code from those other libraries directly into our C++ file, so the C modules need to be legal C++ as well. There are a number of annoying little differences between C and C++, but if you're going to intermix the two languages, you're going to have to know how to cope with them regardless.



            Another tricky part of doing this is that the order of the #includes is more sensitive than the order of library references if a linker command. When you bypass the linker in this way, you end up having to do some things manually that the linker would otherwise do for you automatically.



            To prove the point, I took MiniBasic (your own example) and converted its script.c driver program to a standalone C++ program that says #include <basic.c> instead of #include <basic.h>. (patch) Just to prove that it's really a C++ program now, I changed all the printf() calls to cout stream insertions.



            I had to make a few other changes, all of them well within a normal day's work for someone who's going to intermix C and C++:



            1. The MiniBasic code makes use of C's willingness to tolerate automatic conversions from void* to any other pointer type. C++ makes you be explicit.


            2. Newer compilers are no longer tolerating use of C string constants (e.g. "Hello, world!n") in char* contexts. The standard says the compiler is allowed to place them into read-only memory, so you need to use const char*.


            That's it. Just a few minutes work, patching GCC complaints.



            I had to make some similar changes in basic.c to those in the linked script.c patch file. I haven't bothered posting the diffs, since they're just more of the same.



            For another way to go about this, study the SQLite Amalgamation, as compared to the SQLite source tree. SQLite doesn't use #include all the other files into a single master file; they're actually concatenated together, but that is also all #include does in C or C++.






            share|improve this answer



























              6












              6








              6








              The main entry point is God. Be it a C or C++ source file, it is the center of the application.




              Only in the same way that nitrogen is the center of a pine tree. It is where everything starts, but there's nothing about C or C++ that makes you put the "center" of your application in main().



              A great many C and C++ programs are built on an event loop or an I/O pump. These are the "centers" of such programs. You don't even have to put these loops in the same module as main().




              Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled.




              It is actually easiest to put main() last in a C or C++ source file.



              C and C++ are not like some languages, where symbols can be used before they are declared. Putting main() first means you have to forward-declare everything else.




              There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over.




              "Tell 'im 'e's dreamin'!"



              OS X and iOS are full of proprietary code, and Microsoft isn't going away any time soon.



              What do Microsoft's current difficulties have to do with your question, anyway? You say you might want to make DLLs, and you mention Automake's inability to cope effectively with Windows. That tells me Microsoft remains relevant in your world, too.




              Static linking is a real bitch.




              Really? I've always found it easier than linking to dynamic libraries. It's an older, simpler technology, with fewer things to go wrong.



              Static linking incorporates the external dependencies into the executable, so that the executable stands alone, self-contained. From the rest of your question, that should appeal to you.




              you can #include the libraries as headers




              No... You #include library headers, not libraries.



              This isn't just pedantry. The terminology matters. It has meaning.



              If you could #include libraries, #include </usr/lib/libfoo.a> would work.



              In many programming languages, that is the way external module/library references work. That is, you reference the external code directly.



              C and C++ are not among the languages that work that way.




              If the C library wasn't designed to conform to C++'s syntax, you're screwed.




              No, you just have to learn to use C++. Specifically here, extern "C".




              How might I write such a thing in preprocessor lingo?




              It is perfectly legal to #include another C or C++ file:



              #include <some/library/main.cpp>

              #include <some/other/library/main.c>
              #include <some/other/library/secondary_module.c>

              #include <iostream>

              int main()

              call_the_library();
              do_other_stuff();
              return 0;



              We don't use extern "C" here because this pulls the C and C++ code from those other libraries directly into our C++ file, so the C modules need to be legal C++ as well. There are a number of annoying little differences between C and C++, but if you're going to intermix the two languages, you're going to have to know how to cope with them regardless.



              Another tricky part of doing this is that the order of the #includes is more sensitive than the order of library references if a linker command. When you bypass the linker in this way, you end up having to do some things manually that the linker would otherwise do for you automatically.



              To prove the point, I took MiniBasic (your own example) and converted its script.c driver program to a standalone C++ program that says #include <basic.c> instead of #include <basic.h>. (patch) Just to prove that it's really a C++ program now, I changed all the printf() calls to cout stream insertions.



              I had to make a few other changes, all of them well within a normal day's work for someone who's going to intermix C and C++:



              1. The MiniBasic code makes use of C's willingness to tolerate automatic conversions from void* to any other pointer type. C++ makes you be explicit.


              2. Newer compilers are no longer tolerating use of C string constants (e.g. "Hello, world!n") in char* contexts. The standard says the compiler is allowed to place them into read-only memory, so you need to use const char*.


              That's it. Just a few minutes work, patching GCC complaints.



              I had to make some similar changes in basic.c to those in the linked script.c patch file. I haven't bothered posting the diffs, since they're just more of the same.



              For another way to go about this, study the SQLite Amalgamation, as compared to the SQLite source tree. SQLite doesn't use #include all the other files into a single master file; they're actually concatenated together, but that is also all #include does in C or C++.






              share|improve this answer
















              The main entry point is God. Be it a C or C++ source file, it is the center of the application.




              Only in the same way that nitrogen is the center of a pine tree. It is where everything starts, but there's nothing about C or C++ that makes you put the "center" of your application in main().



              A great many C and C++ programs are built on an event loop or an I/O pump. These are the "centers" of such programs. You don't even have to put these loops in the same module as main().




              Not only do I want the main entry point to be the first thing that is executed, I also want it to be the first thing that is compiled.




              It is actually easiest to put main() last in a C or C++ source file.



              C and C++ are not like some languages, where symbols can be used before they are declared. Putting main() first means you have to forward-declare everything else.




              There was a time when proprietary and closed-source libraries were common. Thanks to Apple switching to Unix and Microsoft shooting themselves in the foot, that time is over.




              "Tell 'im 'e's dreamin'!"



              OS X and iOS are full of proprietary code, and Microsoft isn't going away any time soon.



              What do Microsoft's current difficulties have to do with your question, anyway? You say you might want to make DLLs, and you mention Automake's inability to cope effectively with Windows. That tells me Microsoft remains relevant in your world, too.




              Static linking is a real bitch.




              Really? I've always found it easier than linking to dynamic libraries. It's an older, simpler technology, with fewer things to go wrong.



              Static linking incorporates the external dependencies into the executable, so that the executable stands alone, self-contained. From the rest of your question, that should appeal to you.




              you can #include the libraries as headers




              No... You #include library headers, not libraries.



              This isn't just pedantry. The terminology matters. It has meaning.



              If you could #include libraries, #include </usr/lib/libfoo.a> would work.



              In many programming languages, that is the way external module/library references work. That is, you reference the external code directly.



              C and C++ are not among the languages that work that way.




              If the C library wasn't designed to conform to C++'s syntax, you're screwed.




              No, you just have to learn to use C++. Specifically here, extern "C".




              How might I write such a thing in preprocessor lingo?




              It is perfectly legal to #include another C or C++ file:



              #include <some/library/main.cpp>

              #include <some/other/library/main.c>
              #include <some/other/library/secondary_module.c>

              #include <iostream>

              int main()

              call_the_library();
              do_other_stuff();
              return 0;



              We don't use extern "C" here because this pulls the C and C++ code from those other libraries directly into our C++ file, so the C modules need to be legal C++ as well. There are a number of annoying little differences between C and C++, but if you're going to intermix the two languages, you're going to have to know how to cope with them regardless.



              Another tricky part of doing this is that the order of the #includes is more sensitive than the order of library references if a linker command. When you bypass the linker in this way, you end up having to do some things manually that the linker would otherwise do for you automatically.



              To prove the point, I took MiniBasic (your own example) and converted its script.c driver program to a standalone C++ program that says #include <basic.c> instead of #include <basic.h>. (patch) Just to prove that it's really a C++ program now, I changed all the printf() calls to cout stream insertions.



              I had to make a few other changes, all of them well within a normal day's work for someone who's going to intermix C and C++:



              1. The MiniBasic code makes use of C's willingness to tolerate automatic conversions from void* to any other pointer type. C++ makes you be explicit.


              2. Newer compilers are no longer tolerating use of C string constants (e.g. "Hello, world!n") in char* contexts. The standard says the compiler is allowed to place them into read-only memory, so you need to use const char*.


              That's it. Just a few minutes work, patching GCC complaints.



              I had to make some similar changes in basic.c to those in the linked script.c patch file. I haven't bothered posting the diffs, since they're just more of the same.



              For another way to go about this, study the SQLite Amalgamation, as compared to the SQLite source tree. SQLite doesn't use #include all the other files into a single master file; they're actually concatenated together, but that is also all #include does in C or C++.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Aug 5 '14 at 17:29

























              answered Jul 20 '14 at 3:18









              Warren YoungWarren Young

              55k11143147




              55k11143147























                  1














                  gcc will compile C and C and C++ as C++ simply as a result of you naming the files appropriately, the preprocessor doesn't come into that. You'll need extern "C" blocks around your C declarations in your C++ files to make sure the linker can link stuff correctly, though.



                  But what you're describing is almost never going to be helpful. If you're using a library that needs some kind of configuration to compile in the first place, then it's still going to need it if you just try to compile the files directly into your project. Not many real-world non-trivial libraries are pure ISO C that will compile on every platform without modification or some kind of configure script, so you'd be creating complexity most of the time, not reducing it, because you're going to have to deal with that configuration in your own build somehow.






                  share|improve this answer



























                    1














                    gcc will compile C and C and C++ as C++ simply as a result of you naming the files appropriately, the preprocessor doesn't come into that. You'll need extern "C" blocks around your C declarations in your C++ files to make sure the linker can link stuff correctly, though.



                    But what you're describing is almost never going to be helpful. If you're using a library that needs some kind of configuration to compile in the first place, then it's still going to need it if you just try to compile the files directly into your project. Not many real-world non-trivial libraries are pure ISO C that will compile on every platform without modification or some kind of configure script, so you'd be creating complexity most of the time, not reducing it, because you're going to have to deal with that configuration in your own build somehow.






                    share|improve this answer

























                      1












                      1








                      1







                      gcc will compile C and C and C++ as C++ simply as a result of you naming the files appropriately, the preprocessor doesn't come into that. You'll need extern "C" blocks around your C declarations in your C++ files to make sure the linker can link stuff correctly, though.



                      But what you're describing is almost never going to be helpful. If you're using a library that needs some kind of configuration to compile in the first place, then it's still going to need it if you just try to compile the files directly into your project. Not many real-world non-trivial libraries are pure ISO C that will compile on every platform without modification or some kind of configure script, so you'd be creating complexity most of the time, not reducing it, because you're going to have to deal with that configuration in your own build somehow.






                      share|improve this answer













                      gcc will compile C and C and C++ as C++ simply as a result of you naming the files appropriately, the preprocessor doesn't come into that. You'll need extern "C" blocks around your C declarations in your C++ files to make sure the linker can link stuff correctly, though.



                      But what you're describing is almost never going to be helpful. If you're using a library that needs some kind of configuration to compile in the first place, then it's still going to need it if you just try to compile the files directly into your project. Not many real-world non-trivial libraries are pure ISO C that will compile on every platform without modification or some kind of configure script, so you'd be creating complexity most of the time, not reducing it, because you're going to have to deal with that configuration in your own build somehow.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jul 20 '14 at 3:57









                      Paul GriffithsPaul Griffiths

                      1514




                      1514





















                          1














                          No, you can't do that. There's no gcc pragma for compile in this way.
                          The most similar is the Microsoft Visual C++ #pragma comment(lib, …) or #pragma comment(linker, …) [1] [2] for noting that some libraries should be included in the link procedure.




                          Hi, GCC. How are you doing? In case you forgot, this source file
                          you're looking at right now is written in C++. You should of course
                          compile it with G++. There's another file that this file needs, but
                          it's written in C. It's called "lolcats.c". I want you to compile that
                          one with GCC into an object file and I want you to compile this one
                          with G++ into the main object file, then I want you to link them
                          together into an executable file.




                          Your request is exactly what a Makefile does.



                          You could create a shell script that extracts the source files and compiles them with whatever command you want to use. But it's The Wrong Solution™



                          If you have multiple files, store them as multiple files. If you want people not to use make or cmake, don't provide a Makefile/CMakefile. Give them for instance a compile-me.sh file.



                          The only case when I feel I am in a similar situation is whan I code a util in a single file, but I simply provide the compilation command at the top inside a comment.






                          share|improve this answer



























                            1














                            No, you can't do that. There's no gcc pragma for compile in this way.
                            The most similar is the Microsoft Visual C++ #pragma comment(lib, …) or #pragma comment(linker, …) [1] [2] for noting that some libraries should be included in the link procedure.




                            Hi, GCC. How are you doing? In case you forgot, this source file
                            you're looking at right now is written in C++. You should of course
                            compile it with G++. There's another file that this file needs, but
                            it's written in C. It's called "lolcats.c". I want you to compile that
                            one with GCC into an object file and I want you to compile this one
                            with G++ into the main object file, then I want you to link them
                            together into an executable file.




                            Your request is exactly what a Makefile does.



                            You could create a shell script that extracts the source files and compiles them with whatever command you want to use. But it's The Wrong Solution™



                            If you have multiple files, store them as multiple files. If you want people not to use make or cmake, don't provide a Makefile/CMakefile. Give them for instance a compile-me.sh file.



                            The only case when I feel I am in a similar situation is whan I code a util in a single file, but I simply provide the compilation command at the top inside a comment.






                            share|improve this answer

























                              1












                              1








                              1







                              No, you can't do that. There's no gcc pragma for compile in this way.
                              The most similar is the Microsoft Visual C++ #pragma comment(lib, …) or #pragma comment(linker, …) [1] [2] for noting that some libraries should be included in the link procedure.




                              Hi, GCC. How are you doing? In case you forgot, this source file
                              you're looking at right now is written in C++. You should of course
                              compile it with G++. There's another file that this file needs, but
                              it's written in C. It's called "lolcats.c". I want you to compile that
                              one with GCC into an object file and I want you to compile this one
                              with G++ into the main object file, then I want you to link them
                              together into an executable file.




                              Your request is exactly what a Makefile does.



                              You could create a shell script that extracts the source files and compiles them with whatever command you want to use. But it's The Wrong Solution™



                              If you have multiple files, store them as multiple files. If you want people not to use make or cmake, don't provide a Makefile/CMakefile. Give them for instance a compile-me.sh file.



                              The only case when I feel I am in a similar situation is whan I code a util in a single file, but I simply provide the compilation command at the top inside a comment.






                              share|improve this answer













                              No, you can't do that. There's no gcc pragma for compile in this way.
                              The most similar is the Microsoft Visual C++ #pragma comment(lib, …) or #pragma comment(linker, …) [1] [2] for noting that some libraries should be included in the link procedure.




                              Hi, GCC. How are you doing? In case you forgot, this source file
                              you're looking at right now is written in C++. You should of course
                              compile it with G++. There's another file that this file needs, but
                              it's written in C. It's called "lolcats.c". I want you to compile that
                              one with GCC into an object file and I want you to compile this one
                              with G++ into the main object file, then I want you to link them
                              together into an executable file.




                              Your request is exactly what a Makefile does.



                              You could create a shell script that extracts the source files and compiles them with whatever command you want to use. But it's The Wrong Solution™



                              If you have multiple files, store them as multiple files. If you want people not to use make or cmake, don't provide a Makefile/CMakefile. Give them for instance a compile-me.sh file.



                              The only case when I feel I am in a similar situation is whan I code a util in a single file, but I simply provide the compilation command at the top inside a comment.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Jul 20 '14 at 13:59









                              ÁngelÁngel

                              1,358512




                              1,358512





















                                  0














                                  You could decide that all your things are plugins. Then compile them with gcc -shared -fPIC -O thing1.cc -o thing1.so and have a main stub program doing dlopen(3) on ./thing1.so then dlsym on God; on Linux you could have binfmt_misc tricks to make that more transparent.



                                  If you insist on having self-containing programs, notice that GCC has the -ffreestanding option. It is then up to you to provide a runtime environment (at the very least, for some basic I/O thru system calls which you would need to interface, see syscalls(2)). Study carefully the relevant ABI spec. For Linux/x86-64 it is here. Read about calling conventions.



                                  You could also customize GCC with compiler plugins like MELT (then you could add a #pragma which would do arbitrary things, perhaps even forking a gcc...)



                                  BTW, an entry point like your God is not a source file, but some label known to the linker.



                                  Reading more about compilers, linkers (see Levine's book: Linkers and Loaders, object files, ELF, libraries and shared objects (see Drepper's paper: How to Write Shared Libraries ...), crt0.o should help.



                                  See also the C++ module draft proposal N3347






                                  share|improve this answer





























                                    0














                                    You could decide that all your things are plugins. Then compile them with gcc -shared -fPIC -O thing1.cc -o thing1.so and have a main stub program doing dlopen(3) on ./thing1.so then dlsym on God; on Linux you could have binfmt_misc tricks to make that more transparent.



                                    If you insist on having self-containing programs, notice that GCC has the -ffreestanding option. It is then up to you to provide a runtime environment (at the very least, for some basic I/O thru system calls which you would need to interface, see syscalls(2)). Study carefully the relevant ABI spec. For Linux/x86-64 it is here. Read about calling conventions.



                                    You could also customize GCC with compiler plugins like MELT (then you could add a #pragma which would do arbitrary things, perhaps even forking a gcc...)



                                    BTW, an entry point like your God is not a source file, but some label known to the linker.



                                    Reading more about compilers, linkers (see Levine's book: Linkers and Loaders, object files, ELF, libraries and shared objects (see Drepper's paper: How to Write Shared Libraries ...), crt0.o should help.



                                    See also the C++ module draft proposal N3347






                                    share|improve this answer



























                                      0












                                      0








                                      0







                                      You could decide that all your things are plugins. Then compile them with gcc -shared -fPIC -O thing1.cc -o thing1.so and have a main stub program doing dlopen(3) on ./thing1.so then dlsym on God; on Linux you could have binfmt_misc tricks to make that more transparent.



                                      If you insist on having self-containing programs, notice that GCC has the -ffreestanding option. It is then up to you to provide a runtime environment (at the very least, for some basic I/O thru system calls which you would need to interface, see syscalls(2)). Study carefully the relevant ABI spec. For Linux/x86-64 it is here. Read about calling conventions.



                                      You could also customize GCC with compiler plugins like MELT (then you could add a #pragma which would do arbitrary things, perhaps even forking a gcc...)



                                      BTW, an entry point like your God is not a source file, but some label known to the linker.



                                      Reading more about compilers, linkers (see Levine's book: Linkers and Loaders, object files, ELF, libraries and shared objects (see Drepper's paper: How to Write Shared Libraries ...), crt0.o should help.



                                      See also the C++ module draft proposal N3347






                                      share|improve this answer















                                      You could decide that all your things are plugins. Then compile them with gcc -shared -fPIC -O thing1.cc -o thing1.so and have a main stub program doing dlopen(3) on ./thing1.so then dlsym on God; on Linux you could have binfmt_misc tricks to make that more transparent.



                                      If you insist on having self-containing programs, notice that GCC has the -ffreestanding option. It is then up to you to provide a runtime environment (at the very least, for some basic I/O thru system calls which you would need to interface, see syscalls(2)). Study carefully the relevant ABI spec. For Linux/x86-64 it is here. Read about calling conventions.



                                      You could also customize GCC with compiler plugins like MELT (then you could add a #pragma which would do arbitrary things, perhaps even forking a gcc...)



                                      BTW, an entry point like your God is not a source file, but some label known to the linker.



                                      Reading more about compilers, linkers (see Levine's book: Linkers and Loaders, object files, ELF, libraries and shared objects (see Drepper's paper: How to Write Shared Libraries ...), crt0.o should help.



                                      See also the C++ module draft proposal N3347







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Jul 20 '14 at 13:17

























                                      answered Jul 20 '14 at 11:31









                                      Basile StarynkevitchBasile Starynkevitch

                                      8,0862041




                                      8,0862041



























                                          draft saved

                                          draft discarded
















































                                          Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid


                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.

                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function ()
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f145527%2fcompiling-c-c-code-by-way-of-including-preprocessor-build-instructions-in-an-a%23new-answer', 'question_page');

                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown






                                          Popular posts from this blog

                                          How to check contact read email or not when send email to Individual?

                                          Bahrain

                                          Postfix configuration issue with fips on centos 7; mailgun relay