I'm rather new to Linux filesystems, so could you help me, please? I have to write a sample C++ project (tests) using Ubuntu.
Could you clarify me with a file/folder structure from a developer's perspective? Here are some questions I would like answered:
Answers and links would be appreciated. Thank you.
Where is typical location of the projects (sources, object files, etc.)?
I store my projects in $HOME/dev
but its entirely up to you.
Where is a typical place for dev environment (Eclipse, QT Creator, etc.)?
I use eclipse and set its workspace pointing to $HOME/dev
.
Where is a typical place for the libraries? Are there different places for binaries and for header-only libraries?
Typically libraries are installed to /usr/lib
and headers are installed to /usr/include
.
Where is a typical place for a various tools for the development (code analyser, git client, etc.)?
Typically these are installed into /usr/bin
. I also put tools in $HOME/bin
, especially if I made them.
But its more complicated than that. What if you want to develop/test an application with a version of a library that is different to the one that comes with your Linux distribution? Sometimes I will install different library versions in my $HOME/dev
folder and compile against those rather than the system version.
Also I run Fedora 21
that comes with GCC 4.9.2
, however I have installed GCC 5.1.0
into /opt/gcc-5.1.0
and use that for some things.
A typical project structure for me would be something like:
$HOME/
/dev/
/my-prog/
/src/
/include/
/my-prog.h
/my-prog.cpp
/build-debug/
/src/
/my-prog
/build-release/
/src/
/my-prog
/Makefile
The implementation varies somewhat between Linux distributions, but all seek to implement the Linux Filesystem Hierarchy Standard for the most part. Some distributions more so than others. The latest version is 2.3 and can be viewed via the links in the URL above or directly via FHS 2.3 PDF
Take time to view the document and compare it with the implementation Ubuntu uses. It will provide you with a good background to where and why files are located where they are in Linux, and also give you a quick lesson on how this is more of a goal for distributions than a hard requirement, as distributions are pretty much free to put things anywhere they want.
As for your project source tree layout, a common setup looks like this:
src/
this is were your .cpp
files goinclude/
for header that should get installed when you are writing a librarydata/
is where graphics, icons, sounds, etc. goexternal/
for git submodules or external libraries your project requires and that are obscure enough that you don't want users to manually install themNaming and organisation can of course vary between projects, there is no real standard, some use Source/
instead of src/
. Some might have the headers within the src/
directory and so on. It's really up to your projects needs. If a library is commonly shipped with most distributions there is no need to include it in the source tree. Same with most programming tools, git, gcc and Co. are provided by the Linux distribution and you don't have to worry about where they go.
If you are writing a library you might also want to looking into pkg-config
and the .so
naming rules.
As for installation directories, the FHS explains that in detail, short summary:
/usr/bin
for executables/usr/lib
for public libraries/usr/lib/${APPNAME}
for private libraries/usr/include
for public header files/usr/share/${APPNAME}
for data files/opt/${APPNAME}
is used by some commercial products instead of spreading the data over the hierachy/usr
itself is reserved for distribution installed packages, manually compiled stuff should go to /usr/local
instead. Most build systems will have a --prefix=PREFIX
option to allow the user to change that.
If you need to compile a library yourself, I would generally recommend to avoid installing it into /usr/local
, as uninstalling software from there is hard and it also makes it impossible to keep different versions of the same software around at the same time.
Instead install software it into a PREFIX of it's own, something like ~/run/somelibrary-0.0.1
. Installing software in such a way has however the disadvantage that tools won't find it. You can fix that by setting a few environment variables, I use a simple bash function for that purpose:
function activateprefix {
PREFIX="$1"; \
export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig/"; \
export LD_LIBRARY_PATH="${PREFIX}/lib/"; \
export LD_RUN_PATH="${PREFIX}/lib/"; \
export LIBRARY_PATH="${PREFIX}/lib/"; \
export CPLUS_INCLUDE_PATH="${PREFIX}/include/"; \
export C_INCLUDE_PATH="${PREFIX}/include/"; \
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With