I have an externally built static library (outside of premake). What kind of library directive do I use to tell it to include that in the make file. I'm building on OSX and it seems that static libraries need to be included with the ".o" object files in the compile command. Right now I'm just manually hacking this into the makefile, but it's ugly. I remember trying to do this for weeks and not finding a solution. I decided to come back and try again after a few months.
Any ideas? Maybe there's something painfully obvious.
thx
eris
Related
I am building a small library of my own *.c & *.h files and am not sure how I should manage them, especially when including them into a project. I'm using Codeblocks on Ubuntu in case that matters. For each .c/.h file pair, I have a Codeblocks project that is a playground where I can modify & test out any changes or newfound bugs.
I'm thinking I should compile the .c into libraries (.a/.so), put them into respective custom 'XXX/bin' and 'XXX/include' folders, and include/link from those locations (add to the PATH).
The other option (which I've been doing for right or wrong) is to add the .c file directly to my project and #include the full path of the .h file (I know this is wrong, but it works).
How do you all manage your .c and .h files?
Actually, both ways (prepare object files and use headers with them when compile program, and add source code and headers to each project with full or relative path) are quite normal. You should choose a way that is convenient for you. I do not know how Codeblocks works, but I suppose that as most IDE it can support dependencies, optimize build time and rebuild libraries (components of complex project) if some files were updated.
My suggestion is to consider some project build tools (project makers) like cmake. You will be able to configure building process for any project and to use different compilers, as well as different compiling options for different projects, while source files (*.c and *.h) storage is unchanged.
Start from cmake tutorial and other documentation
Of course, at first it will be not easy to deal with the makefile syntax, but when you get used to it you will realize how much it's convenient.
I think it is possible to include headers from their exact source, on a linux platform at least.
assume that you put your *.h in /usr/include you can just use
#include "/usr/include/*.h"
w/o moving your source files you can add the same chunk of code to every new sources you write, but VolAnd's above mentioned suggestions are probably more standard ways of managing.
I'm using NetBeans 7.0.1 to learn C.
I have done all the pre-requisites to start compiling in NetBeans so I'm ok with that.
I have done a "HelloWorld.c" with a main() in it and it runs fine. But then I made "Another.c" with its respective main(). I got an error which describes that I have already declared a main().
How can I have a .c files collection in the same project with their respective mains? I'm doing this because I require the learning of the language since I switched some roles at work.
Is there a way so NetBeans can handle all the .c without a project? Or should i try this in Visual Studio 2010?
The problem is that you can only have one main() per executable, but you're compiling the two files into on executable. When it links them it's spotting that the main() function exists in both of the files it's linking together and consequently reports this.
The solution is to make netbeans build you two, separate executables from each file. The easiest way to do this is to simply make two independent projects.
There is also a slightly messy way of making this work within a single netbeans project, but I wouldn't recommend it unless you have a compelling reason. The other workaround would be to write your own makefile to build two binaries, instead of using the netbeans managed one.
I would like to have control over the type of the libraries that get found/linked with my binaries in CMake. The final goal is, to generate binaries "as static as possible" that is to link statically against every library that does have a static version available. This is important as would enable portability of binaries across different systems during testing.
ATM this seems to be quite difficult to achieve as the FindXXX.cmake packages, or more precisely the find_library command always picks up the dynamic libraries whenever both static and dynamic are available.
Tips on how to implement this functionality - preferably in an elegant way - would be very welcome!
I did some investigation and although I could not find a satisfying solution to the problem, I did find a half-solution.
The problem of static builds boils down to 3 things:
Building and linking the project's internal libraries.
Pretty simple, one just has to flip the BUILD_SHARED_LIBS switch OFF.
Finding static versions of external libraries.
The only way seems to be setting CMAKE_FIND_LIBRARY_SUFFIXES to contain the desired file suffix(es) (it's a priority list).
This solution is quite a "dirty" one and very much against CMake's cross-platform aspirations. IMHO this should be handled behind the scenes by CMake, but as far as I understood, because of the ".lib" confusion on Windows, it seems that the CMake developers prefer the current implementation.
Linking statically against system libraries.
CMake provides an option LINK_SEARCH_END_STATIC which based on the documentation: "End a link line such that static system libraries are used."
One would think, this is it, the problem is solved. However, it seems that the current implementation is not up to the task. If the option is turned on, CMake generates a implicit linker call with an argument list that ends with the options passed to the linker, including -Wl,-Bstatic. However, this is not enough. Only instructing the linker to link statically results in an error, in my case: /usr/bin/ld: cannot find -lgcc_s. What is missing is telling gcc as well that we need static linking through the -static argument which is not generated to the linker call by CMake. I think this is a bug, but I haven't managed to get a confirmation from the developers yet.
Finally, I think all this could and should be done by CMake behind the scenes, after all it's not so complicated, except that it's impossible on Windows - if that count as complicated...
A well made FindXXX.cmake file will include something for this. If you look in FindBoost.cmake, you can set the Boost_USE_STATIC_LIBS variable to control whether or not it finds static or shared libraries. Unfortunately, a majority of packages do not implement this.
If a module uses the find_library command (most do), then you can change CMake's behavior through CMAKE_FIND_LIBRARY_SUFFIXES variable. Here's the relevant CMake code from FindBoost.cmake to use this:
IF(WIN32)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ELSE(WIN32)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ENDIF(WIN32)
You can either put this before calling find_package, or, better, you can modify the .cmake files themselves and contribute back to the community.
For the .cmake files I use in my project, I keep all of them in their own folder within source control. I did this because I found that having the correct .cmake file for some libraries was inconsistent and keeping my own copy allowed me to make modifications and ensure that everyone who checked out the code would have the same build system files.
My executable needs zlib1.dll to run,
and I need to keep them together now and then.
How can I merge it into the executable to save the trouble?
I'm using cmake to build the executable.
UPDATE
zlib1.dll is not directly included by my programe,but required by libpng14-14.dll(one dll of the gtk bundle)
It sounds like you want to link statically so that your program does not require the presence of zlib1.dll in order to run. But zlib1.dll is a dynamic link library (that's what DLL stands for!), so you can't link it statically. The first thing you need to do is find a static version of this library. On windows, it will normally end with the .lib extension.
I'm not familiar with cmake, so I'll let someone else answer the part of the question about how to make cmake use the static library, once you have both.
Sorry there is no way to mix it. Either you must compile and link statically or dynamically. I tried it - it does not work.
So if libpng.dll needs a zlib.dll you can't turn zlib into a static library. You have to also compile libpng as a static library.
I've done this a few times, the makefiles from PNG, ZLIB, (and also the JPEG, TIFF image format libraries) are pretty good. If you need more then 30min to figure out what to do, you should look at it as a good training on your C makefile skills.
I'm developing a shared library, and since the code is big, I've decided to split it in many headers and source files, like any normal program :).
The problem is that most of these headers are for internal use, i.e. I don't want them to be accessible from outside of my library. So I'm thinking to move them all to a big source file and only provide headers for what is going to be visible.
It's a good idea do that? Should I worry on visibility?
Thanks
Instead of merging the headers, just keep them alongside your source files and don't "publish" them as a part of your development package. As an example of this, the linux kernel has many headers in the source tree, but only certain headers are exposed to applications (in the include structure).
You should approach it from a "cleanliness" angle; don't ship headers which include functions you aren't intending people to call. Don't document functions which you aren't shipping headers for.
If someone really wants to call a function in your library, they can, but you should try to make it clear that that's an unsupported use case and it's their problem if it all goes wrong.
Yes you should worry about symbol visibility. On Windows, set up to use DLLEXPORT. On Linux, define DLLEXPORT to set default symbol visibility, but compile everything with -fvisibility=hidden. There's an Ulrich Drepper article on it that is useful.
For the include files, you can separate them into directories and/or you can use your packaging system to just copy the public files.