0

I have a project comprised of tasks. Each task has three subdirectories: input, code, and output. In the code directory resides a Makefile with the recipes needed to make the output from the code and inputs. Each Makefile uses Unix commands.

Many tasks are connected: the output from one is the input to the other. These connections are done with Unix-style symlinks (ln -s in the Makefile).

I'd like to be able to ship this project to any OS (Windows, Mac, Linux) and have it run. The symlinks work well on Mac and Linux, but not Windows. I know that Windows 10 has its own symlink syntax (mklink).

I can think of a few potential solutions, but I'm not sure if they're feasible let alone how to implement them. One would be to have the Makefile detect the OS and construct the symlink accordingly. Another would be to have Windows users replicate the project (e.g., git clone) into a Unix-like file system (WSL2 ideally, or a VM) and run the Makefiles there. The second is worse than the first, in my experience, because editing the files then becomes a pain relative to using one's native file system. I run Windows on my laptop, so ease of editing is high on my list.

To summarize, I think there are three ordered questions here:

  1. Can a makefile detect the OS and make the correct symlinks / can it make OS-agnostic symlinks?
  2. If not, is there a way to do this all in the Linux file system of WSL2? One would need to be able to edit files with Emacs or Atom and run Windows executables (otherwise I'd have to go put Stata, R, Matlab and whatever else in my WSL2 Ubuntu distro). I'm not a huge fan of VSCode, so I'd prefer to stay away from it, but I know Windows has made strides in integrating that with WSL2.
  3. If none of this works, would something like CMake help, or should I just switch to Linux and hang Windows users out to dry?
3
  • 1
    You can always use the appropriate absolute or relative file spec instead of a symlink ...
    – DavidPostill
    Commented Aug 31, 2019 at 21:10
  • Why do you choose symlink at first choice? Is symlink necessary for your project?
    – Biswapriyo
    Commented Sep 4, 2019 at 7:55
  • I'm following the project architecture discussed in this video. For tasks early in the project the input/output files are often rather large data sets, so symlinks are helpful so that we aren't carrying around multiple copies of the same data set. I'm open to alternative solutions, though!
    – Levi Crews
    Commented Sep 4, 2019 at 14:00

1 Answer 1

0

There is an easy way to detect OS with makefile. Here are two project setup for example.

First, if the project has different directory for different OS and each folder contains their own makefile and the folder structure is similar as following:

/src
|
+-- folder_win
|   |
|   +-- makefile_win
|
+-- folder_linux
|   |
|   +-- makefile_linux
|
+-- folder_mac
|   |
|   +-- makefile_mac
|
+-- MAKEFILE

Then the root makefile (here MAKEFILE) can be written as follows:

ifeq ($(OS), Windows_NT)
    cd folder_win; $(MAKE) -f makefile_win
else
    UNAME_S := $(shell uname -s)
    ifeq ($(UNAME_S), Linux
        cd folder_linux; $(MAKE) -f makefile_linux
    endif
    ifeq ($(UNAME_S), Darwin)
        cd folder_mac; $(MAKE) -f makefile_mac
    endif
endif

Second, if there is one makefile and the same source code depends on the OS then modify the code as following (in C/C++) and repeat these for others:

#ifdef WIN_OS
// Do Windows things
#endif

And the makefile will be as previous but with a little change:

ifeq ($(OS), Windows_NT)
    CCOPT := -DWIN_OS
endif

$(CC) $(CCOPT) $(CFLAGS) file.c

Then add the other OS options with same conditions as before.

Source: OS detecting makefile

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .